From 36e8dce048b0ecac0b8a9270d90cd88f8abc5d46 Mon Sep 17 00:00:00 2001 From: andig Date: Thu, 27 Mar 2025 09:01:15 +0100 Subject: [PATCH] Circuit: add retry (#20151) --- core/circuit/circuit.go | 22 ++++++++++++++-------- core/circuit/helper.go | 12 ++++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 core/circuit/helper.go diff --git a/core/circuit/circuit.go b/core/circuit/circuit.go index 76fd821f1..051fef087 100644 --- a/core/circuit/circuit.go +++ b/core/circuit/circuit.go @@ -7,6 +7,7 @@ import ( "sync" "time" + "github.com/cenkalti/backoff/v4" "github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/plugin" "github.com/evcc-io/evcc/util" @@ -234,7 +235,7 @@ func (c *Circuit) overloadOnError(t time.Time, val *float64) { } func (c *Circuit) updateMeters() error { - if f, err := c.meter.CurrentPower(); err == nil { + if f, err := backoff.RetryWithData(c.meter.CurrentPower, bo()); err == nil { c.power = f c.powerUpdated = time.Now() } else { @@ -243,6 +244,16 @@ func (c *Circuit) updateMeters() error { } if phaseMeter, ok := c.meter.(api.PhaseCurrents); ok { + var i1, i2, i3 float64 + if err := backoff.Retry(func() error { + var err error + i1, i2, i3, err = phaseMeter.Currents() + return err + }, bo()); err != nil { + c.overloadOnError(c.currentUpdated, &c.current) + return fmt.Errorf("circuit currents: %w", err) + } + var p1, p2, p3 float64 if phaseMeter, ok := c.meter.(api.PhasePowers); ok { var err error // phases needed for signed currents @@ -251,13 +262,8 @@ func (c *Circuit) updateMeters() error { } } - if i1, i2, i3, err := phaseMeter.Currents(); err == nil { - c.current = max(util.SignFromPower(i1, p1), util.SignFromPower(i2, p2), util.SignFromPower(i3, p3)) - c.currentUpdated = time.Now() - } else { - c.overloadOnError(c.currentUpdated, &c.current) - return fmt.Errorf("circuit currents: %w", err) - } + c.current = max(util.SignFromPower(i1, p1), util.SignFromPower(i2, p2), util.SignFromPower(i3, p3)) + c.currentUpdated = time.Now() } return nil diff --git a/core/circuit/helper.go b/core/circuit/helper.go new file mode 100644 index 000000000..77c88c8b4 --- /dev/null +++ b/core/circuit/helper.go @@ -0,0 +1,12 @@ +package circuit + +import ( + "time" + + "github.com/cenkalti/backoff/v4" +) + +// bo returns an exponential backoff for reading meter power quickly +func bo() *backoff.ExponentialBackOff { + return backoff.NewExponentialBackOff(backoff.WithInitialInterval(20*time.Millisecond), backoff.WithMaxElapsedTime(time.Second)) +}