-
-
Notifications
You must be signed in to change notification settings - Fork 896
Keba: use enable / current register for failsafe heartbeat #21228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @mfuchs1984 - I've reviewed your changes and they look great!
Here's what I looked at during the review
- 🟡 General issues: 1 issue found
- 🟢 Testing: all looks good
- 🟢 Complexity: all looks good
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
@@ -41,6 +42,8 @@ type Keba struct { | |||
*embed | |||
log *util.Logger | |||
conn *modbus.Connection | |||
mu sync.Mutex | |||
enabled bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Local enabled
flag not initialized from hardware on startup
Because enabled
defaults to false, the first heartbeat can disable an already-on charger. Initialize it in setup (e.g., via wb.Enabled()
) to match the hardware state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guter Gedanke, aber ist das wirklich ein Problem beim Start von evcc? Wenn ja, dann vermutlich auch ein Problem bei der alfen, wo es entsprechend current betrifft.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stimmt, ohne Initialisierung kann beim ersten Heartbeat aus Versehen ein „Disable“ auf einen bereits aktiven Wallbox-Ausgang geschickt werden. Das gleiche gilt übrigens für die Alfen-Implementierung: dort ist der lokale current
-Wert 0 und der erste Heartbeat setzt dann ebenfalls 0 A.
Mein Vorschlag wäre daher, direkt in Setup()
den Ist-Zustand vom Ladestrom bzw. von Enabled()
auszulesen und das lokale Flag entsprechend zu setzen. Beispiel (vereinfacht):
func (wb *Keba) Setup() error {
// … bestehende Initialisierung …
state, err := wb.Enabled()
if err != nil {
return fmt.Errorf("keba: enabled initial read failed: %w", err)
}
wb.mu.Lock()
wb.enabled = state
wb.mu.Unlock()
return nil
}
Und analog bei Alfen:
func (wb *Alfen) Setup() error {
cur, err := wb.Current()
if err != nil {
return fmt.Errorf("alfen: current initial read failed: %w", err)
}
wb.mu.Lock()
wb.current = cur
wb.mu.Unlock()
return nil
}
Damit verhindert man, dass der allererste Heartbeat einen falschen Schreibvorgang auslöst. Wenn das für dich ok ist, kann ich das in den PR aufnehmen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mfuchs1984 das gleiche Problem ist mir auch beim refactoring des Heartbeats aufgefallen weshalb der PR noch offen ist. Da haben wir bei vielen Boxen ein kleines Logikproblem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bin echt überrascht über die Qualität des AI Reviews.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hast du schon einen Plan für die Lösung? Vorher auslesen wie hier vorgeschlagen klingt erstmal plausibel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Genau, ich würde das wie im Alfen-Beispiel direkt in Setup()
beim Hochfahren auslesen und ins lokale Flag schreiben. Dann schieben spätere Heartbeats nichts Ungewolltes mehr. Grob sähe das für Keba so aus:
func (wb *Keba) Setup(log *util.Logger) error {
// 1) bestehende Initialisierung (Connection, embed, etc.)
if err := wb.embed.Setup(log); err != nil {
return err
}
// 2) Ist-Zustand vom Enabled-Register auslesen
state, err := wb.Enabled()
if err != nil {
return fmt.Errorf("keba: enabled initial read failed: %w", err)
}
// 3) ins lokale Flag schreiben
wb.mu.Lock()
wb.enabled = state
wb.mu.Unlock()
wb.log.Infof("keba: initial enabled state = %v", state)
return nil
}
Analog können wir beim Alfen-Adapter wb.Current()
in Setup()
auslesen und wb.current
setzen.
Damit ist sichergestellt, dass der allererste Heartbeat nicht versehentlich „0 A“ bzw. „Disable“ schreibt, nur weil unser lokaler Default anders ist. Wenn das so für dich passt, kann ich das direkt in den PR übernehmen.
Der sehr gute Test von @Myky09 hat noch eine kleine Lücke aufgedeckt, update kommt bald. |
@andig das aufgedeckte Problem ist m.E. doch etwas größer. Und zwar wird Line 1861 in 3721eff
Line 898 in 3721eff
enabled != lp.enable nach dem Aufruf von Line 1844 in 3721eff
Das bedeutet, dass |
Fix #21093
According to #21093 (reply in thread) Keba stated that just reading the Enabled register in the heartbeat function is not sufficient to reset the failsafe timeout. Instead, renewing current or enabled register will do the job.
So I used the exisiting Enable function and implemented the same pattern as in https://github.com/evcc-io/evcc/blob/master/charger/alfen.go (where instead of enabled, current is used).
Since I don't have a Keba Wallbox, it is currently untested. @Myky09, a test run would be appreciated. If you are able to compile and run evcc, you can do it any time with a binary created from the source branch. Otherwise, you can test a nightly version in case the evcc decides to merge this change.