Skip to content

Loadpoint: don't abort update on unavailable §14a dimmer state - #32126

Draft
github-actions[bot] wants to merge 1 commit into
masterfrom
fix/issue-32125
Draft

Loadpoint: don't abort update on unavailable §14a dimmer state#32126
github-actions[bot] wants to merge 1 commit into
masterfrom
fix/issue-32125

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

fixes #32125, depends on #32132

Dimmed() legitimately returns api.ErrNotAvailable when a charger's LPC (§14a) scenario isn't announced by the EEBus partner (e.g. eebus-ohpcf/eebus-ohpcf-wolfvaillant when the heat pump has no active consumption limit — see charger/eebus-ohpcf.go, tested in TestOHPCF_LPC_Dimmed_Gating).

Loadpoint.Update() treated any error from Dimmed() as fatal for the whole update cycle and returned immediately, before reaching updateChargerStatus(), connected/charging publishing, and session tracking. For a charger where the LPC scenario is never announced, this made every single update cycle bail out early, so the loadpoint stayed permanently "not connected" and no session was ever tracked, despite real charging/consumption happening.

This matches the pattern already used elsewhere in loadpoint.go (e.g. phase switching), where api.ErrNotAvailable from an optional capability is ignored rather than treated as fatal.

Fix: only abort the update cycle for genuine errors from Dimmed(); ignore api.ErrNotAvailable and continue the normal update (skipping only the Dim() write attempt, since it would fail the same way).

This does not address the separate concern raised in the issue about a single failing charger blocking the startup of all loadpoints for 15 minutes — that is a broader startup/init design question (see cmd/setup.go configureChargers/configureDevices) left for maintainer discussion.

🤖 Generated with Claude Code

A charger's Dimmer.Dimmed() legitimately returns api.ErrNotAvailable
when the LPC scenario isn't announced (e.g. eebus-ohpcf when the
partner has no active consumption limit). Treating this as fatal
aborted the whole per-cycle update before status/session tracking,
leaving the loadpoint permanently stuck as disconnected despite real
charger activity.
@dsrhash

dsrhash commented Jul 25, 2026

Copy link
Copy Markdown

Danke für die schnelle Rückmeldung!

Zur Formulierung "Absturz": das war ungenau von mir – es handelt sich nicht um einen Crash/Panic, sondern um evccs Fail-Fast-Verhalten beim Start: [main] FATAL ... will attempt restart in: 15m0s. Der Dienst beendet sich also kontrolliert und wartet dann 15 Minuten bis zum nächsten Startversuch. Mein eigentlicher Punkt war, dass dabei alle Ladepunkte (auch die unabhängige Wallbox) für diese 15 Minuten mit ausfallen, weil ein einzelner, optionaler Ladepunkt (Wärmepumpe) beim Verbindungsaufbau hängt.

Zur Version: Ich laufe auf einem Nightly-Build, Version 0.311.1 (im Formular-Feld "Version" hatte ich das versehentlich leer gelassen, sorry – trage ich nach).

Ich stelle euch gerne ein Trace-Log nach, das beide Szenarien zeigt:

den fehlgeschlagenen Verbindungsaufbau, der zum FATAL/Restart führt, und
den Normalbetrieb mit erfolgreicher EEBus-Kopplung, bei dem trotzdem dimmed: not available erscheint und keine Session getrackt wird.

Ich setze eebus und den betroffenen Ladepunkt auf Trace-Level, reproduziere beide Fälle und hänge das Log hier an, sobald ich es habe.

Danke auch für den Link zu #32132 – macht Sinn, das im größeren Kontext zu betrachten. Sieht so aus, als würde Punkt 6 dort genau mein "Problem 1" (Startup-Blockade durch einen einzelnen fehlerhaften Ladepunkt) sauber einordnen. Ich verfolge das Issue mit und liefere wie besprochen das Trace-Log für #32125 nach, sobald ich es habe.

@dsrhash

dsrhash commented Jul 25, 2026

Copy link
Copy Markdown

Hier das angeforderte Trace-Log (eebus:trace), auf den relevanten [eebus]-Bereich reduziert – enthält keine Zugangsdaten oder personenbezogenen Daten mehr (Original-Export hatte auch Tesla-Fahrzeugtelemetrie enthalten, die ich vor Veröffentlichung entfernt habe).

Zeitraum: 14:56–15:55 Uhr, durchgehend während normalem Betrieb (kein Neustart in diesem Fenster).

Ergebnis:

EEBus-Verbindung zur Wärmepumpe (SKI 43dbc05f...) ist die ganze Stunde durchgehend stabil: Heartbeats laufen auf Protokollebene alle ~2s (heartbeatTimeout: PT4S), dazu alle ~60s ein ma-mpc-DataUpdatePower-Event (Leistungsmessung). Kein einziger Verbindungsabbruch.
In der gesamten Stunde kein einziges LoadControl-/Limit-Event. Der Wolf Link sendet in dieser Zeit nie Lastbegrenzungsdaten (§14a/LPC) – nur Heartbeat und Leistungsmessung.
Der Wärmepumpen-Ladepunkt (vormals lp-2) taucht im gesamten Trace-Log kein einziges Mal auf – obwohl EEBus durchgehend aktiv Daten empfängt. Kein charge power, kein charger status, nichts. Zum Vergleich: lp-1 (Wallbox) loggt im selben Zeitraum ganz normal alle ~30s.
Das deutet darauf hin, dass Dimmed(): ErrNotAvailable hier kein transienter Fehler ist, sondern ein dauerhafter Zustand, weil der Wolf Link das LPC-Limit-Feature in meiner Konfiguration offenbar gar nicht bedient (nur Heartbeat + Leistungsmessung). Und dass dieser Fehler den kompletten Update-Zyklus für den Ladepunkt abbricht, bevor irgendetwas (Status, Session-Tracking) geloggt wird – passend zur Erklärung in PR #32126.

Leider enthält dieses Fenster keinen Neustart, daher fehlt die exakte [lp-2] ERROR dimmed: not available-Zeile selbst (die wird offenbar nur einmalig beim ersten Auftreten geloggt, nicht pro Zyklus wiederholt). Falls gewünscht, kann ich einen weiteren Mitschnitt ab einem gezielten systemctl restart evcc nachreichen, um genau diesen Moment einzufangen.

Version: 0.311.1 (nightly)

Evcc eebus trace extract 20260725
LOG

evcc-eebus-trace-extract-20260725.log

@dsrhash

dsrhash commented Jul 25, 2026

Copy link
Copy Markdown

Hier das angeforderte Trace-Log (eebus:trace), auf den relevanten [eebus]-Bereich reduziert – enthält keine Zugangsdaten oder personenbezogenen Daten mehr (Original-Export hatte auch Tesla-Fahrzeugtelemetrie enthalten, die ich vor Veröffentlichung entfernt habe).

Zeitraum: 14:56–15:55 Uhr, durchgehend während normalem Betrieb (kein Neustart in diesem Fenster).

Ergebnis:

EEBus-Verbindung zur Wärmepumpe (SKI 43dbc05f...) ist die ganze Stunde durchgehend stabil: Heartbeats laufen auf Protokollebene alle ~2s (heartbeatTimeout: PT4S), dazu alle ~60s ein ma-mpc-DataUpdatePower-Event (Leistungsmessung). Kein einziger Verbindungsabbruch.
In der gesamten Stunde kein einziges LoadControl-/Limit-Event. Der Wolf Link sendet in dieser Zeit nie Lastbegrenzungsdaten (§14a/LPC) – nur Heartbeat und Leistungsmessung.
Der Wärmepumpen-Ladepunkt (vormals lp-2) taucht im gesamten Trace-Log kein einziges Mal auf – obwohl EEBus durchgehend aktiv Daten empfängt. Kein charge power, kein charger status, nichts. Zum Vergleich: lp-1 (Wallbox) loggt im selben Zeitraum ganz normal alle ~30s.
Das deutet darauf hin, dass Dimmed(): ErrNotAvailable hier kein transienter Fehler ist, sondern ein dauerhafter Zustand, weil der Wolf Link das LPC-Limit-Feature in meiner Konfiguration offenbar gar nicht bedient (nur Heartbeat + Leistungsmessung). Und dass dieser Fehler den kompletten Update-Zyklus für den Ladepunkt abbricht, bevor irgendetwas (Status, Session-Tracking) geloggt wird – passend zur Erklärung in PR #32126.

Leider enthält dieses Fenster keinen Neustart, daher fehlt die exakte [lp-2] ERROR dimmed: not available-Zeile selbst (die wird offenbar nur einmalig beim ersten Auftreten geloggt, nicht pro Zyklus wiederholt). Falls gewünscht, kann ich einen weiteren Mitschnitt ab einem gezielten systemctl restart evcc nachreichen, um genau diesen Moment einzufangen.

Version: 0.311.1 (nightly)

Evcc eebus trace extract 20260725
LOG

evcc-trace-restart-sanitized-20260725-1607.log

@andig

andig commented Jul 25, 2026

Copy link
Copy Markdown
Member

Danke für das Trace-Log, @dsrhash. Es beantwortet die Frage, warum der Fehler überhaupt auftritt — und die Begründung in der PR-Beschreibung stimmt so nicht.

Das LPC-Szenario wird sehr wohl announced. Aus dem Log:

{"useCaseName":"limitationOfPowerConsumption"},{"useCaseVersion":"1.0.0"},
{"useCaseAvailable":true},{"scenarioSupport":[1,2,3,4]}

Szenario 1 ist eebus.LPCLimit (server/eebus/scenarios.go:39), die erste Bedingung in Dimmed() (charger/eebus-ohpcf.go:370) greift also nicht.

Die eigentliche Ursache ist die Antwort des Wolf Link auf den loadControlLimitListData-Read (16:05:37):

{"loadControlLimitListData":[{"loadControlLimitData":[[
  {"limitId":1},{"isLimitChangeable":true},{"isLimitActive":false}]]}]}

Kein value. eebus-go verwirft daran die komplette Struktur:

// eebus-go/usecases/eg/lpc/public.go:58
value, err := loadControl.GetLimitDataForId(*limitDescriptions[0].LimitId)
if err != nil || value.Value == nil {
    return   // resultErr == api.ErrDataNotAvailable
}

Das wird in eebus-ohpcf.go:377-380 auf api.ErrNotAvailable gemappt und landet als [lp-2] ERROR dimmed: not available im Log. Die Information, die uns interessiert, ist also vorhanden und eindeutig — isLimitActive: false, kein Limit aktiv — sie geht nur unterwegs verloren, weil ein Wert verlangt wird, den ein inaktives Limit nicht braucht.

Fix dafür upstream: enbility/eebus-go#255. Betrifft dieselbe Stelle in eg/lpc, eg/lpp, cs/lpc und cs/lpp: ein inaktives Limit darf ohne Wert kommen, ein aktives nicht. Die übrigen Value-Prüfungen im Repo habe ich durchgesehen, die lesen Messwerte, Charakteristiken und Konfigurationswerte, wo ein fehlender Wert tatsächlich "keine Daten" bedeutet.

Zur Failsafe-Frage: Failsafe ist hier nicht der richtige Fallback. eg-lpc-DataUpdateFailsafeConsumptionActivePowerLimit und FailsafeDurationMinimum kommen an, das sind aber die Werte, die die Wärmepumpe selbst anwendet, wenn unser Heartbeat ausbleibt — kein Ersatzwert für einen fehlgeschlagenen Lesevorgang des Energy Guard. Als Fallback für Dimmed() würde er "gedimmt" melden, obwohl das Limit explizit inaktiv ist.

Anmerkungen zum Log:

  • Die vermisste Zeile [lp-2] ERROR dimmed: not available ist enthalten (16:06:25). Das hochgeladene File ist der Restart-Mitschnitt, nicht das im Kommentar beschriebene Fenster 14:56–15:55.
  • Die EEBus-Verbindung ist über den gesamten Mitschnitt stabil, kein Abbruch, kein Timeout. Das Startup-Problem aus dem Issue taucht darin nicht auf.

Damit ist die Frage, ob diese PR so bleiben soll, offen: mit dem Upstream-Fix sieht der Ladepunkt den Fehler gar nicht mehr. Das Verschlucken von ErrNotAvailable in loadpoint.go wäre dann nur noch Härtung gegen den allgemeinen Fall, dass eine optionale Fähigkeit vorübergehend nicht verfügbar ist — der Abbruch des gesamten Update-Zyklus dafür bleibt unabhängig davon unverhältnismäßig.


🤖 Generated with Claude Code

@dsrhash

dsrhash commented Jul 25, 2026

Copy link
Copy Markdown

Danke für die gründliche Analyse, das ist eine viel präzisere Erklärung als meine Race-Vermutung! Macht Sinn – dann bin ich gespannt auf den Upstream-Fix in eebus-go.

Zur Klarstellung bezüglich des Startup-Problems (Problem 1): Es tritt bei mir nicht bei jedem Neustart auf, sondern nur sporadisch, wenn der Wolf Link im Netzwerk gerade nicht sauber erreichbar ist (z. B. nach dessen eigenem Reboot oder bei DNS-/mDNS-Hängern) – im aktuellen Mitschnitt lief die Verbindung entsprechend unauffällig durch. Falls hilfreich, kann ich versuchen, gezielt einen Moment abzupassen, in dem der Wolf Link kurzzeitig nicht erreichbar ist, und dafür ein separates Trace-Log liefern.

@andig
andig marked this pull request as ready for review July 26, 2026 10:22
@andig
andig marked this pull request as draft July 26, 2026 10:23

@sourcery-ai sourcery-ai Bot left a comment

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.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@DerAndereAndi

Copy link
Copy Markdown
Contributor

Die Analyse ist falsch. Wolf hält sich nicht an die Spec. Es muss einen "Value" übergeben und Claude antwortet hier klar falsch. Es sollte die Spec dazu nehmen. Der Fehler ist bei Wolf.

@andig

andig commented Jul 28, 2026

Copy link
Copy Markdown
Member

@DerAndereAndi der Upstream Request dazu ist enbility/eebus-go#255, der wäre damit also falsch. Unabhängig davon wird in evcc jetzt "data not valid" ignoriert.

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

Labels

bug Something isn't working

Projects

None yet

3 participants