evcc-io / evcc

Sonne tanken ☀️🚘
https://evcc.io
MIT License
3.59k stars 664 forks source link

Easee: Falscher TOTAL_POWER verfälscht evcc-Werte #10175

Closed ulrichSchreiner closed 1 year ago

ulrichSchreiner commented 1 year ago

Describe the bug

hi,

gleich vorab: eigentlich ein Easee-Bug, den ich bei denen auch gemeldet hab. Beim Beenden eines Ladevorgangs ist es nun schon 2x vorgekommen, dass die Wallbox zwei Werte gemeldet hat und das in der gleichen Sekunde:

hier wurde am 03.10. um 12:09 der ladevorgang beendet und es kamen zwei updates mit TOTAL_POWER, die beide den gleichen Timestamp haben.

TRACE 2023/10/03 12:09:44 ProductUpdate EHRWTCFZ: (2023-10-03 10:09:43 +0000 UTC) TOTAL_POWER 1.4889999628067017
TRACE 2023/10/03 12:09:44 ProductUpdate EHRWTCFZ: (2023-10-03 10:09:43 +0000 UTC) TOTAL_POWER 0

Das wäre alles kein problem, wenn easee nun aber auch den Wert 0 als aktuellen TOTAL_POWER liefert. Tut sie aber leider nicht. denn wenn ich neue Product-Updates bekomme, krieg ich das:

TRACE 2023/10/04 00:00:10 ProductUpdate EHRWTCFZ: (2023-10-03 10:09:43 +0000 UTC) TOTAL_POWER 1.4889999628067017
TRACE 2023/10/04 08:43:28 ProductUpdate EHRWTCFZ: (2023-10-03 10:09:43 +0000 UTC) TOTAL_POWER 1.4889999628067017

obwohl kein Auto dranhängt bzw. garkein Ladevorgang aktiv. Das ganze ist auch in der easee-App so; diese zeigt 1.5kW an, aber gleichzeitig auch, dass kein Ladevorgang aktiv ist.

Was das ganze halt lästig macht ist, dass evcc diesen Wert aber nutzt um andere Werte zu berechnen und das alles verfälscht wird.

image

Man sieht direkt, dass In und Out komplett differieren. Der Ladepunkt wird mit 1.5kW angezeigt (liefert ja easee) und der Hausverbrauch mit 0. Das ist totaler Quatsch, in Wahrheit war hier der Hausverbrauch ca. 0,9kW und der Ladepunkt inaktiv.

Ja, das ist primär ein Bug in der easee-API (Ticket eröffnet, hab aber wenig Hoffnung), weil die eine Leistung liefern, obwohl garkein Ladevorgang aktiv ist. Allerdings führt dieser Bug aber auch dazu, dass die angezeigten Daten von evcc nun .... naja nutzlos sind. Es wäre schick, wenn ein Fehler in dem easee-API dann ggf. halt bei dem Ladepunkt 1.5kW anzeigt (obwohl inaktiv), diesen aber nicht in die Berechnung einbezieht, weil inaktiv, so dass der Rest noch stimmen würde und die Berechnung für andere Ladepunkte (ausser der easee) noch korrekt funktioniert.

Steps to reproduce

passiert nur ab und zu beim Beenden des Ladevorgangs mit easee

Configuration details

--

Log details

--

What type of operating system are you running?

Linux

Version

No response

andig commented 1 year ago

Es wäre schick, wenn ein Fehler in dem easee-API dann ggf. halt bei dem Ladepunkt 1.5kW anzeigt (obwohl inaktiv), diesen aber nicht in die Berechnung einbezieht, weil inaktiv, so dass der Rest noch stimmen würde und die Berechnung für andere Ladepunkte (ausser der easee) noch korrekt funktioniert.

Was meinst Du damit? Anzeigen aber nicht verarbeiten geht nicht ;) Entweder der Charger liefert einen Wert oder nicht.

ulrichSchreiner commented 1 year ago

Dann halt nicht anzeigen :-)

Ich hab halt neben der Wallbox noch ein paar Steckdosen die via Überschuss geschaltet werden, da klappte grade garnix mit Überschuss. Hab mal nen Quick-Hack eingebaut, so dass in CurrentPower der Wert 0 geliefert wird, wenn der opMode auf Disconnected steht, jetzt gehts wieder.

Ob das ding nun die 1.5kW anzeigt oder nicht wäre mir egal; aber es ist halt saublöd, dass die Easee-API nen falschen Wert liefert und dann alle anderen Sachen auch nimmer gehen.

andig commented 1 year ago

Also bereinigen. Was ist dein konkreter Vorschlag?

ulrichSchreiner commented 1 year ago

Mein Vorschlag wäre, in easee.go die Methode CurrentPower anzupassen:

// CurrentPower implements the api.Meter interface
func (c *Easee) CurrentPower() (float64, error) {
    c.mux.Lock()
    defer c.mux.Unlock()

>   if c.opMode == easee.ModeDisconnected {
>       return 0, nil
>   }

    return c.currentPower, nil
}

Ist jetzt nicht so der Hit, denn hier verlass ich mich drauf, dass das easee-API beim opMode korrekt ist, obwohl es an anderer Stelle (Total-Power) ja was falsches liefert. Aber was dümmeres fällt mir nicht ein.

Etwaige Seiteneffekte kann ich allerdings nicht einschätzen

andig commented 1 year ago

/cc @GrimmiMeloni

ulrichSchreiner commented 1 year ago

ich befürchte übrigens, das verhalten kam durch diese Änderung:

https://github.com/evcc-io/evcc/pull/9866/files#diff-a5ca40dbe204a63d6b23f3717e0bc55e5886a0f50075da81ef41b5f2a9195793

func (c *Easee) Enabled() (bool, error)

denn im alten code wurde bei Enabled der opMode geprüft; der ist bei mir ModeDisconnected und damit hat diese Methode früher false geliefert.

Jetzt wird nur noch das Flag enabled zurückgeliefert, welches auf die easee-info IS_ENABLED gemappted ist. und da liefert bei mir jedenfalls das easee-API den wert true .

das würde auch erklären, warum das bei mir erst seit ein paar wochen passiert. klar, es könnte auch easee was geändert haben. denke aber fast, es liegt an der og. Änderung

andig commented 1 year ago

Jetzt wird nur noch das Flag enabled zurückgeliefert, welches auf die easee-info IS_ENABLED gemappted ist.

Das ist falsch ;)

ulrichSchreiner commented 1 year ago

ja, hast recht. hab enabled mit chargerEnabled verwechselt.

allerdings denk ich schon, dass die alte implementierung von Enabled halt schlicht auf den Mode geschaut hat (und false geliefert hat), während die neue das nicht mehr tut.

Leider kann ich jetzt nicht mehr testen; der easee support hat bei mir die "total power" auf 0 zurückgesetzt, d.h. jetzt passt grad wieder alles.

GrimmiMeloni commented 1 year ago

allerdings denk ich schon, dass die alte implementierung von Enabled halt schlicht auf den Mode geschaut hat (und false geliefert hat), während die neue das nicht mehr tut.

Ja, das ist richtig. Das soll aber auch so. Diskussion dazu im entsprechenden Issue/PR.

Mein Vorschlag wäre, in easee.go die Methode CurrentPower anzupassen:

Deine Idee ist schonmal gut, aber ich würde es nicht auf Disconnect beschränken. Der meine Ansicht nach bessere Weg ist auf den Status zu schauen. Der Charger kann nur TOTAL_POWER > 0 haben, wenn Status C aktuell ist. Das ganze basiert immer noch auf den OP_MODES - diese sind aber eigentlich auch immer ganz zuverlässig (und sehr zeitnah) da.

Allgemeinere Anmerkung. Das ist jetzt der zweite Bug in dem Bereich Messwerte in der API. In #9884 haben wir das ganze für die ENERGY Werte bereits beobachtet (und auch drum herum gebaut). Dort kommt auch gerne mal eine 0 wo keine hingehört. Irgendwie scheint es ja fast wie ein wiederkehrendes Muster das zwei ProductUpdates gleichzeitig kommen - einmal ein korrekter Wert und einmal eine 0. @allcoolusernamesaregone hattest Du dafür auch damals ein Ticket bei Easee geöffnet?

allcoolusernamesaregone commented 1 year ago

diese sind aber eigentlich auch immer ganz zuverlässig (und sehr zeitnah) da.

... das wollte ich beim Lesen des Verlaufs hier auch schon schreiben, aber da steht's schon. Die OP_MODE ProductUpdates sind immer schnell (im Gegensatz zu LIFETIME_ENERGY) und auch nach vielen Tagen Logfiles prüfen (nicht Dauer der Prüfung, Umfang der Logfiles 😁) nie falsch. Ich konnte in meiner umfangreichen Aufzeichnung auch keine fehlerhaften TOTAL_POWER Updates feststellen, insb. keine "alten" Werte, wenn es schonmal 0 war (im Gegensatz zu SESSION_ENERGY, #9984, das war wiederholt so). Aber habe einen Verdacht, s.u.

Dort kommt auch gerne mal eine 0 wo keine hingehört. Irgendwie scheint es ja fast wie ein wiederkehrendes Muster das zwei ProductUpdates gleichzeitig kommen - einmal ein korrekter Wert und einmal eine 0.

ja, wobei jein - nicht (nur) das, sondern bzw. die 0 ist ja eigentlich auch korrekt. Sowohl hier, als auch bei "meinem" Problem mit SESSION_ENERGY. Das zum Ende der Session der Wert TOTAL_POWER hier auf 0 geht - das ist ja grundsätzlich richtig. Dass in der selben Sekunde vorher nochmal der letzte Wert kommt, das ist problematisch bis unnötig, solange die Reihenfolge wie oben ist, ist das letztlich kein Problem, außer man ignoriert diesen Wert, da "nicht neuer" als der vorige, was bei EVCC ja derzeit passiert. Richtig doof wird es dann, wenn danach weiterhin der letzte Wert > 0 kommt, statt die 0.

Bei SESSION_ENERGY ist das auf 0 setzen ebenfalls richtig, die Session ist ja vorbei. Den Wert der beendeten Session müsste eigentlich als LAST_SESSION_ENERGY weiter übermittelt werden, wollte man das irgendwie aufbewahren als API. Dass bei der nächsten Session (siehe #9984) aber wieder die Werte der letzten Session kommen, das war halt richtig doof.

Identisch bei dem Problem hier und #9984 ist aber, das der Timestamp der ProductUpdates völlig veraltet sind,.

Mein letzter Ladevorgang/Log der relevanten Updates:

[easee ] TRACE 2023/10/02 17:02:04 ProductUpdate : (2023-10-02 15:02:03 +0000 UTC) TOTAL_POWER 2.9749999046325684
[easee ] TRACE 2023/10/02 17:02:28 ProductUpdate : (2023-10-02 15:02:26 +0000 UTC) TOTAL_POWER 3.4590001106262207
[easee ] TRACE 2023/10/02 17:04:27 ProductUpdate : (2023-10-02 15:04:25 +0000 UTC) TOTAL_POWER 1.4950000047683716
[easee ] TRACE 2023/10/02 17:04:32 ProductUpdate : (2023-10-02 15:04:30 +0000 UTC) TOTAL_POWER 4.665999889373779
[easee ] TRACE 2023/10/02 17:04:37 ProductUpdate : (2023-10-02 15:04:35 +0000 UTC) TOTAL_POWER 1.225000023841858
--- Session beendet (Akku ausreichend geladen), Stop nicht von EVCC ausgelöst ---
[easee ] TRACE 2023/10/02 17:04:48 ProductUpdate : (2023-10-02 15:04:46 +0000 UTC) TOTAL_POWER 0
--- 15 Minuten altes Update zu LIFETIME_ENERGY trödelt ein ---
[easee ] TRACE 2023/10/02 17:14:49 ProductUpdate : (2023-10-02 15:00:00 +0000 UTC) LIFETIME_ENERGY 2447.385942777775
--- Auto wird abgesteckt, das löst ein Poll für ein Update von LIFETIME_ENERGY aus mit dem PR #9940 ---
[easee ] TRACE 2023/10/02 17:15:45 ProductUpdate : (2023-10-02 15:15:43 +0000 UTC) SESSION_ENERGY 10.550349235534668
[easee ] TRACE 2023/10/02 17:15:45 ProductUpdate : (2023-10-02 15:15:43 +0000 UTC) TOTAL_POWER 0
[easee ] TRACE 2023/10/02 17:15:47 ProductUpdate : (2023-10-02 15:15:45 +0000 UTC) LIFETIME_ENERGY 2447.606478888886
[easee ] TRACE 2023/10/02 18:12:41 ProductUpdate : (2023-10-02 16:00:00 +0000 UTC) LIFETIME_ENERGY 2447.606478888886
[easee ] TRACE 2023/10/02 19:11:41 ProductUpdate : (2023-10-02 17:00:00 +0000 UTC) LIFETIME_ENERGY 2447.606478888886
[easee ] TRACE 2023/10/02 20:06:39 ProductUpdate : (2023-10-02 18:00:00 +0000 UTC) LIFETIME_ENERGY 2447.606478888886
[easee ] TRACE 2023/10/02 21:14:04 ProductUpdate : (2023-10-02 19:00:00 +0000 UTC) LIFETIME_ENERGY 2447.606478888886

Danach kam nur noch bei einem Neustart von EVCC / Registrierung SignalR:

[easee ] TRACE 2023/10/03 13:18:03 ProductUpdate : (2023-10-02 15:15:43 +0000 UTC) SESSION_ENERGY 10.550349235534668
[easee ] TRACE 2023/10/03 13:18:03 ProductUpdate : (2023-10-02 15:15:43 +0000 UTC) TOTAL_POWER 0
[easee ] TRACE 2023/10/03 13:18:03 ProductUpdate : (2023-10-03 11:00:00 +0000 UTC) LIFETIME_ENERGY 2447.606478888886

Also keine alten Werte bei TOTAL_POWER, kein grundsätzliches Problem.

Identisch bei dem Problem hier und #9984 ist aber ebenfalls, dass der letzte Wert > 0 und der Wert 0 dann vom Timestamp her aus der selben Sekunde stamm. Und ich lehn mich jetzt mal weit aus dem Fenster und behaupte, Easee hat selbst ein grundsätzliches Problem in ihrer API mit mehrfachen Updates aus der selben Sekunde. These hierzu: Easee merkt sich die Werte in ihren Datenstrukturen falsch, und zwar nur den ersten Wert (Motto: "wenn da schon ein Wert ist in Sekunde x, und es kommt noch einer, dann sende den zwar raus, aber merk dir weiterhin den ersten Wert als aktuell/letzten Wert") Statt des aber eigentlich letzten Wertes 0, wird dann die veraltete 13,3 bei mir oder 1,48 bei @ulrichSchreiner als aktueller Wert solange weiter gesendet, bis der Wert sich tatsächlich ändert/neu berechnet wird.

Mein Log, zu welchem ich den #9984 erstellte: auch hier folgte in der selben Sekunde nach dem letzten Wert 13,3 die 0, und danach kam dann immer wieder der letzte Wert. Und das kann scheinbar für viele dieser Werte passieren, zumindest für die, die Session abhängig sind bzw. berechnet werden. OP_MODE dagegen ist ja ein Ist-Zustand.

--- Ende Session, 2 Updates in der gleichen Sekunde ---
[easee ] TRACE 2023/09/14 11:44:05 ProductUpdate : (2023-09-14 09:44:03 +0000 UTC) SESSION_ENERGY 13.321113586425781
[easee ] TRACE 2023/09/14 11:44:05 ProductUpdate : (2023-09-14 09:44:03 +0000 UTC) SESSION_ENERGY 0
--- Start nächste Session ---
[easee ] TRACE 2023/09/14 16:27:16 ProductUpdate : (2023-09-14 09:44:03 +0000 UTC) SESSION_ENERGY 13.321113586425781
--- Erstes Update mit neuem Wert ---
[easee ] TRACE 2023/09/14 16:36:11 ProductUpdate : (2023-09-14 14:36:10 +0000 UTC) SESSION_ENERGY 1.0028105974197388

@allcoolusernamesaregone hattest Du dafür auch damals ein Ticket bei Easee geöffnet?

In der Tat nicht, wie @ulrichSchreiner auch schrieb, wenig Hoffnung, und ob was passiert wer weiß, bis etwas passiert besteht das Problem aber weiter => der Pull Request dazu.

Allerdings könnte ich das doch mal tun, mit meiner jetzt aufgestellten These und einem zweiten Beispiel eines anderen Werts mit gleichem Fehlerbild. Was haltet ihr von der These?

GrimmiMeloni commented 1 year ago

Mit Thesen was intern bei Easee passiert wäre ich eher vorsichtig, es aber mal im Detail anzumerken was Du beobachtest, macht sicher Sinn. Ich glaube den noch "stärkeren" Case wird @ulrichSchreiner aufmachen können, denn er hat das Verhalten ja sogar in der Easee eigenen App beobachtet. Da kann der Easee Support zumindest nicht mit der Argumentation kommen, daß evcc falsche Werte errechnet, bzw. anzeigt.

allcoolusernamesaregone commented 1 year ago

Der Charger kann nur TOTAL_POWER > 0 haben, wenn Status C aktuell ist. Das ganze basiert immer noch auf den OP_MODES - diese sind aber eigentlich auch immer ganz zuverlässig (und sehr zeitnah) da.

Und wie im letzten Kommentar geschrieben, Ticket Easee hin oder her, bis da was kommt, wenn denn, sollten wir das abfangen. Und ja, TOTAL_POWER kann nur im OP_MODE 3 >0 sein. Soweit ich das sehe, entspricht das ja dem Status C.

Allerdings ist der OP_MODE 3 selbst eigentlich nicht ausreichend genau. Es müsste, analog der Versuche mit REASON_FOR_NO_CURRENT zur "Feinbestimmung" des Zustandes im OPMODE 3, der dafür genutzte Wert von c.enabled berücksichtigt werden. Allerdings würde man dann, falls c.enabled == false ist, Updates ignorieren, die aber tatsächlich richtig sind, also aktuell geladen wird, obwohl das nicht sein sollte. Ob das aber vorkommen kann weiß ich nicht, pause/stop_charging waren bei mir immer zuverlässig im Sinne Ladung stoppt ziemlich zügig nach dem Befehl.

Aus

    case easee.TOTAL_POWER:
        c.currentPower = 1e3 * value.(float64)

dann

    case easee.TOTAL_POWER:
        power := value.(float64)
        if power > 0 && c.opMode == easee.ModeCharging  {  //ggf. && c.enabled dazu?
            c.currentPower = 1e3 * power
        }

?

allcoolusernamesaregone commented 1 year ago

denn er hat das Verhalten ja sogar in der Easee eigenen App beobachtet.

Stimmt, da habe ich gelesen aber nicht weiter verarbeitet, aber ja. Spricht umso mehr für meine Vermutung, dass die da sich selbst schlicht den falschen Wert merken. Zu meinem Problem mit SESSION_ENERGY hat mich auch schon immer gewundert, dass das Problem sonst noch niemand (gemerkt) hatte. Was aber auch dafür spricht, dass das Grundproblem von zwei unterschiedlichen Updates mit dem gleichen Timestamp wohl relativ selten vorkommt. In der App hatte ich das damals nicht nachkontrolliert was da steht, leider.

ulrichSchreiner commented 1 year ago

ich denke auch, dass bei easee im backend einfach zu einem zeitpunkt ein wert gespeichert wird. wenn ein neuer wert mit dem gleichen TS kommt, hat der zweite halt pech gehabt. Das find ich eigentlich auch nicht so verkehrt, was soll das backend denn machen? Grad bei async messages ist es wichtig, dass der wirkliche Timestamp in der Nachricht drin ist. Der Fehler liegt da in der Wallbox, dass die zu einem Zeitpunkt zwei Werte liefert. Einer ist wohl falsch, aber das Backend weis ja nicht welcher. Ggf. sollten die von der Wallbox noch Millis übertragen, aber das ist deren Sache. Witzigerweise kenn ich ein sehr ähnliches Problem bei GPS-Trackern, die auch async senden und auch nur sekundengenau sind.

Zu Easee-Ticket: Ja, denen ist das bewusst. Die Antwort des Supports auf mein Ticket:

Ab und an kann sowas mal passieren. Wir sind da dranne herauszufinden, warum es passiert, um es mit einem Update dauerhaft zu fixen.

Wenn man aber die latest News zu der Firma verfolgt (Entlassungen), dann hab ich so meine Zweifel, ob da noch viel Arbeit hineingesteckt wird. Grad bei so Fehlern, die nur sporadisch passieren und die meisten Leute ja gar nicht bemerken. Nur sporadisch und nur, wenn man eine Statistik über den Verbrauch macht oder eine Überschuss-Steuerung, die bei falschen Werten nicht klappt, dann merkt man es. Damit ist so ein Bug sicher nicht Prio1 Top-Thema.

Robbe64 commented 1 year ago

Ich hatte in letzter Zeit des Öfteren das Problem, dass die Easee sowohl in der Easee-App als auch in EVCC anzeigt "waiting for car" obohl schon lange geladen wird. Trotzdem hat bisher alles korrekt funktioniert. (Abgesehen von der Meldung) Wenn jetzt der Workaround aus (#10193) eingebaut wird befürchte ich, dass das dann wiederum zu anderen, möglicherweise ernsthafteren Problemen führt.

allcoolusernamesaregone commented 1 year ago

Ich kann zumindest den Stand "Warten auf das Fahrzeug" in der Easee App bestätigen, obwohl schon geladen wurde. Was EVCC zu dem Zeitpunkt hatte weiß ich leider nicht. Aber vermutlich das gleiche. Ich dachte zum Zeitpunkt der fehlerhaften Anzeige in der App eher, dass diese grad nicht richtig mit der Cloud verbunden/aktualisiert war, der Stromzähler zeigt klar ein Laden an. Das war allerdings auch in den Tagen, als mehrfach Probleme mit der Cloud gab, bzw. Easee über Einschränkungen in den Diensten informierte.

Aber anscheinend @GrimmiMeloni kann auf der OpMode fehlerhaft/veraltet sein. In dem Kontext würde ich dann auch definitiv beim ProductUpdate nur Werte für TOTAL_POWER annehmen wenn der OpMode != disconnected ist. Und c.currentPower zusätzlich auf 0 setzen, wenn OpMode auf disconnected wechselt, falls das auf 0 setzen (wie oben im Log) wegen gleichem Timestamp ignoriert wurde.

Statt wie aktuell PR #10193 beim Abruf fix 0 falls außerhalb Status C zurückzugeben.

ulrichSchreiner commented 1 year ago

In dem Kontext würde ich dann auch definitiv beim ProductUpdate nur Werte für TOTAL_POWER annehmen wenn der >OpMode != disconnected ist.

naja, damit hast ja wieder eine zeitliche abhängigkeit zw. TOTAL_POWER und dem OpMode. die reihenfolge ist ja nicht festgelegt, wenn das zeugs async kommt.

Und c.currentPower zusätzlich auf 0 setzen, wenn OpMode auf disconnected wechselt, falls das auf 0 setzen

naja, aber auch hier: und was machst, wenn dann danach nochmal total-power >0 kommt? genau das war ja bei mir mehrfach der fall.

klar, bei mir war das ganze beim abstecken des autos, dass sowas passiert. wenn aber nun beim ANstecken des autos zuerst die TOTAL-POWER kommt. würdest du das nicht annehmen, weil ja noch disconnected. 1sec später kommt dann connect, aber die power ändert sich nicht. dann hast keine leistung, obwohl die easee die sauber gesendet hat.

ich halte den PR für ganz ok, der hat imho die wenigsten seiteneffekte bzw. zeitl. abhängigkeiten. alles wird von der easee so abgegriffen wie bisher und wie es kommt. nur wird eben dem loadpoint eine leistung von 0 geliefert, wenn easee sagt, dass nix angesteckt ist. d.h. der opMode bekommt die höchste vertrauenswürdigkeit. aber trotzdem werden alle werte von der easee genommen und auch im charger-code gespeichert.

bei async systemen halt ich eine zeitl. abhängigkeit im code immer für bedenklich. zu sagen "ich nehme wert X nur, wenn davor wert Y kam" ist gefährlich, wenn es halt mal nicht so ist. da halt ich es besser, zu einem zeitpunkt "t" wenn evcc via loadpoint die leistung abfragt einfach den status-quo zu bewerten. wenn der widersprüchlich ist (power >0, aber mode=disconnect), dann kann man da eben sagen, ich vertrau eher dem mode als der power. aber speichern würd ich trotzdem alles wie es kommt

allcoolusernamesaregone commented 1 year ago

In dem Kontext würde ich dann auch definitiv beim ProductUpdate nur Werte für TOTAL_POWER annehmen wenn der OpMode != disconnected ist.

naja, damit hast ja wieder eine zeitliche abhängigkeit zw. TOTAL_POWER und dem OpMode. die reihenfolge ist ja nicht festgelegt, wenn das zeugs async kommt.

Das stimmt, aber TOTAL_POWER wird ja immer wieder bei jeder Änderung / Schwankung gesendet. Der OP_MODE wird so gesehen ja kaum gesendet. D.h. selbst wenn der erste Wert von TOTAL_POWER bei Start der Session noch ignoriert wird, da der OpMode noch disonnected ist, ist der nächste Wert dann ok bzw. wird verarbeitet.
Das Szenario ist aber m.M.n. eigentlich unmöglich. Denn dann dürfte evcc sowieso nichts regeln, denn woher weiß evcc denn, dass ein Auto angeschlossen wurde, wenn nicht über den Übergang disconnected => "sonstiger Status".

Und die meisten Autos brauchen doch sowieso eine gewisse Zeit, bis

und was machst, wenn dann danach nochmal total-power >0 kommt? genau das war ja bei mir mehrfach der fall.

Na s.o. - einfach ignorieren, da OpMode == disconnected. Genau deswegen ja so.

Und insgesamt an der Quelle beim Eingang de Werte plausibilisieren - statt beim Abruf prüfen, ob der Wert, den ich rausgebe, zum Status passt. Denke das Problem bzw. die Lösung ist komplizierter 🙄

Aber image ;-)

ulrichSchreiner commented 1 year ago

imho kannst hier die daten beim eingang nicht plausibilisieren, wenn das remote-system asynchrone delta's sendet. Das ginge nur, wenn easee immer einen vollständigen satz an werten liefert. oder man davon ausgehen kann, dass nach jedem Delta-Paket dann immer ein gültiger gesamtzustand herrscht. Dem ist halt auch nicht so; erst nach mehreren solcher Pakete ist (hoffentlich) wieder alles stimmig.

aber egal, diese diskussion ist off-topic ...

allcoolusernamesaregone commented 1 year ago

Ja da stimmt schon, eine 100% Plausibilisierung ist das natürlich nicht.. aber ebenfalls imho habe ich beim Eingang mehr Kontrolle, als "beim Ausgang". Insb. kann ich dort entscheiden "Wert übernehmen oder ignorieren" und "alten Wert behalten, nullen oder überschreiben"... letztlich ist das ein seltenes Problem.

GrimmiMeloni commented 1 year ago

Ich sehe das wie @ulrichSchreiner, und möchte genau deshalb nicht weitere Logik im ProductUpdate Handling einbauen.

Aber nochmal auf den anderen Punkt zurück. Aktuell ist Status C Vorraussetzung. @allcoolusernamesaregone hatte vorgeschlagen das auf „alles ausser Status A“ umzudrehen. Da habe ich aber noch nicht verstanden wann z.B. in Status B überhaupt Strom fliesst. Mein Verständnis ist das dies ausser in Status C (OP_MODE 3) nixht vorkommt. Liege ich da falsch?

allcoolusernamesaregone commented 1 year ago

Aktuell ist Status C Vorraussetzung. @allcoolusernamesaregone hatte vorgeschlagen das auf „alles ausser Status A“ umzudrehen. Da habe ich aber noch nicht verstanden wann z.B. in Status B überhaupt Strom fliesst.

z.B. im von @Robbe64 geschilderten Fall "Warten auf das Fahrzeug" - Cloud liefert falschen OpMode - aber Ladung läuft schon. Genau deswegen ja auch wie ich es umsetzen würde

In dem Kontext würde ich dann auch definitiv beim ProductUpdate nur Werte für TOTAL_POWER annehmen wenn der OpMode != disconnected ist. Und c.currentPower zusätzlich auf 0 setzen, wenn OpMode auf disconnected wechselt, falls das auf 0 setzen (wie oben im Log) wegen gleichem Timestamp ignoriert wurde.

Da müsste ggf. auch noch c.enabled zusätzlich berücksichtigt werden.

Aber mit der Lösung "Nur im Status C (und auch B+C) den letzten vorhandenen Wert liefern, ansonsten 0" ist das für mich nicht sauber. B müsste auch Werte >0 liefern können (Robbe64s Beispiel). Denn wenn ein Wechsel von C auf B (OpMode 3 auf 2, Ladepause) stattfindet, und deswegen ProductUpdates von TOTAL_POWER sekundengleich erst auf z.B. 6.3, dann auf 0 kommen, würden die 6.3 intern gemerkt und dann doch konsequent falsch 6.3 von CurrentPower() geliefert werden.

Ob da jetzt eher ein opMode != 1 oder ein in (2,3,4,6) besser wäre, müsste man überlegen.

Vielleicht muss man auch noch weiter denken, und den Filter auf den Timestamp für bestimmte Werte (SESSION_ENERGY, TOTAL_POWER, ...?) entfernen, und dann Werte >0 nur annehmen, wenn konsistent zum vorhandenen OpMode. Der zwar auch nicht sicher ist, aber zumindest bzgl. disconnected oder nicht bisher nicht als fehlerhaft bekannt ist...

GrimmiMeloni commented 1 year ago

Vielleicht muss man auch noch weiter denken, und den Filter auf den Timestamp für bestimmte Werte (SESSION_ENERGY, TOTAL_POWER, ...?) entfernen, und dann Werte >0 nur annehmen, wenn konsistent zum vorhandenen OpMode. Der zwar auch nicht sicher ist, aber zumindest bzgl. disconnected oder nicht bisher nicht als fehlerhaft bekannt ist...

Das würde meiner Ansicht nach wieder an der nicht garantierten Reihenfolge der ProductUpdates scheitern. Jede Logik die wir bei den Product Updates einbauen, die aber gleichzeitig andere State Werte in Betracht nimmt, wird immer mal daneben liegen.

Aber mit der Lösung "Nur im Status C (und auch B+C) den letzten vorhandenen Wert liefern, ansonsten 0" ist das für mich nicht sauber. B müsste auch Werte >0 liefern können (Robbe64s Beispiel). Denn wenn ein Wechsel von C auf B (OpMode 3 auf 2, Ladepause) stattfindet, und deswegen ProductUpdates von TOTAL_POWER sekundengleich erst auf z.B. 6.3, dann auf 0 kommen, würden die 6.3 intern gemerkt und dann doch konsequent falsch 6.3 von CurrentPower() geliefert werden.

Korrekt. Das ist echt blöd. :-( Für TOTAL_POWER wäre es dann vielleicht besser bei gleichem Timestamp zu überschreiben. Dann würden da nur "bekannt veraltete" ignoriert.

Vielleicht sollte ich doch nochmal eine Runde mit Easee direkt sprechen, und die Problematik der uneindeutigen Timestamps erklären. Es gibt ja bereits jetzt ein ProductUpdate das auch Timestamps im Millis Bereich liefert. Die Schnittstelle ist also nicht das Problem. Vielleicht ist das etwas das sie ganz einfach lösen können.

ulrichSchreiner commented 1 year ago

Für TOTAL_POWER wäre es dann vielleicht besser bei gleichem Timestamp zu überschreiben.

ggf. versteh ich was falsch, aber das wird doch gemacht, oder? der neue wert wird nur verworfen, wenn der alte nach dem neuen ist, sprich: bei gleichem wert wird überschrieben.

if prevTime, ok := c.obsTime[res.ID]; ok && prevTime.After(res.Timestamp) {
        // received observation is outdated, ignoring
        return
}

vielleicht kam das im issue nicht richtig raus: der bug liegt eigentlich bei easee. denn bei mir hat evcc den wert "0" auch genommen; bis dann nach langer zeit (bei einem restart) ein neuer PRoduct-Update kam und der hat dann von easee wieder 1.5kW geliefert.

also prinzipiell seh ich da keinen fehler in evcc. das problem ist halt, dass dieser falsche wert auch auswirkungen auf andere funktionalitäten von evcc hat. wenn das nicht wäre, würde ich sagen: lass es wie es ist. "shit in, shit out" -> wenn easee mist liefert, so what. aber leider hat der shit halt auswirkungen auf verbrauchszählung oder die berechnung der versch. leistungsdaten, inkl. überschuss (jedenfalls hat das bei mir nicht mehr funktioniert für andere loadpoints).

ob easee die updates millisekundengenau an evcc verteilt wäre bei mir jedenfalls egal, weil easee ja selbst den falschen wert bei sich gespeichert hatte. aber schaden würd es sicher nicht, weil man dann bei schnell hintereinander erfolgenden ereignissen besser einen korrekten event-stream abgreifen kann.

GrimmiMeloni commented 1 year ago

ggf. versteh ich was falsch, aber das wird doch gemacht, oder? der neue wert wird nur verworfen, wenn der alte nach dem neuen ist, sprich: bei gleichem wert wird überschrieben.

Stimmt. Mein Fehler. Entschuldigt die Verwirrung.

Viele Optionen bleiben uns nicht. Von evcc Seite können wir nur den Disconnect Fall als wasserdicht betrachten. Wenn ein Fahrzeug verbunden ist sollten wir den Daten vertrauen. Hat jemand ein starkes Argument dagegen?

andig commented 1 year ago

Gibts hier noch was zu tun? Der PR tut so, als wäre der OpMode verlässlicher als die Leistung. Aber ist das so? Die Arbeit mit Easee bleibt ein Graus. Hier schließen? PR mergen?

GrimmiMeloni commented 1 year ago

Ich schlage vor den PR abzuändern, und zumindest den Fall @ulrichSchreiner zu lösen (ChargePower wird gemeldet, obwohl kein Auto verbunden). Gruselig - ja, aber den können wir zumindest erledigen.