diff --git a/core/circuit/circuit.go b/core/circuit/circuit.go index c3d3f3983..d8e392262 100644 --- a/core/circuit/circuit.go +++ b/core/circuit/circuit.go @@ -12,6 +12,7 @@ import ( "github.com/evcc-io/evcc/plugin" "github.com/evcc-io/evcc/util" "github.com/evcc-io/evcc/util/config" + "github.com/evcc-io/evcc/util/modbus" ) var _ api.Circuit = (*Circuit)(nil) @@ -235,7 +236,7 @@ func (c *Circuit) overloadOnError(t time.Time, val *float64) { } func (c *Circuit) updateMeters() error { - if f, err := backoff.RetryWithData(c.meter.CurrentPower, bo()); err == nil { + if f, err := backoff.RetryWithData(c.meter.CurrentPower, modbus.Backoff()); err == nil { c.power = f c.powerUpdated = time.Now() } else { @@ -249,7 +250,7 @@ func (c *Circuit) updateMeters() error { var err error i1, i2, i3, err = phaseMeter.Currents() return err - }, bo()); err != nil { + }, modbus.Backoff()); err != nil { c.overloadOnError(c.currentUpdated, &c.current) return fmt.Errorf("circuit currents: %w", err) } diff --git a/core/circuit/helper.go b/core/circuit/helper.go deleted file mode 100644 index 77c88c8b4..000000000 --- a/core/circuit/helper.go +++ /dev/null @@ -1,12 +0,0 @@ -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)) -} diff --git a/core/helper.go b/core/helper.go index d8c2a31a2..5f9fedab4 100644 --- a/core/helper.go +++ b/core/helper.go @@ -2,9 +2,7 @@ package core import ( "fmt" - "time" - "github.com/cenkalti/backoff/v4" "github.com/evcc-io/evcc/util/config" ) @@ -16,11 +14,6 @@ var ( Voltage float64 ) -// bo returns an exponential backoff for reading meter power quickly -func bo() *backoff.ExponentialBackOff { - return backoff.NewExponentialBackOff(backoff.WithInitialInterval(20*time.Millisecond), backoff.WithMaxElapsedTime(2*time.Second)) -} - // powerToCurrent is a helper function to convert power to per-phase current func powerToCurrent(power float64, phases int) float64 { if Voltage == 0 { diff --git a/core/loadpoint.go b/core/loadpoint.go index 8aa9b9f8e..f0ebac21c 100644 --- a/core/loadpoint.go +++ b/core/loadpoint.go @@ -26,6 +26,7 @@ import ( "github.com/evcc-io/evcc/push" "github.com/evcc-io/evcc/util" "github.com/evcc-io/evcc/util/config" + "github.com/evcc-io/evcc/util/modbus" "github.com/evcc-io/evcc/util/telemetry" ) @@ -1461,7 +1462,7 @@ func (lp *Loadpoint) pvMaxCurrent(mode api.ChargeMode, sitePower, batteryBoostPo // UpdateChargePowerAndCurrents updates charge meter power and currents for load management func (lp *Loadpoint) UpdateChargePowerAndCurrents() float64 { - power, err := backoff.RetryWithData(lp.chargeMeter.CurrentPower, bo()) + power, err := backoff.RetryWithData(lp.chargeMeter.CurrentPower, modbus.Backoff()) if err == nil { lp.Lock() lp.chargePower = power // update value if no error @@ -1502,7 +1503,7 @@ func (lp *Loadpoint) UpdateChargePowerAndCurrents() float64 { lp.publish(keys.ChargeCurrents, lp.chargeCurrents) return nil - }, bo()); err != nil && !errors.Is(err, api.ErrNotAvailable) { + }, modbus.Backoff()); err != nil && !errors.Is(err, api.ErrNotAvailable) { lp.log.ERROR.Printf("charge currents: %v", err) } } diff --git a/core/site.go b/core/site.go index da95ed7bc..922b47e34 100644 --- a/core/site.go +++ b/core/site.go @@ -30,6 +30,7 @@ import ( "github.com/evcc-io/evcc/tariff" "github.com/evcc-io/evcc/util" "github.com/evcc-io/evcc/util/config" + "github.com/evcc-io/evcc/util/modbus" "github.com/evcc-io/evcc/util/telemetry" "github.com/samber/lo" "github.com/smallnest/chanx" @@ -496,7 +497,7 @@ func (site *Site) collectMeters(key string, meters []config.Device[api.Meter]) [ fmt.Fprintf(&b, "%v !! %3dms %v\n", start, d.Milliseconds(), err) } return f, err - }, bo()) + }, modbus.Backoff()) if err == nil { site.log.DEBUG.Printf("%s %d power: %.0fW", key, i+1, power) } else { @@ -723,7 +724,7 @@ func (site *Site) updateGridMeter() error { var mm measurement - if res, err := backoff.RetryWithData(site.gridMeter.CurrentPower, bo()); err == nil { + if res, err := backoff.RetryWithData(site.gridMeter.CurrentPower, modbus.Backoff()); err == nil { mm.Power = res site.gridPower = res site.log.DEBUG.Printf("grid power: %.0fW", res) diff --git a/go.mod b/go.mod index 346036c73..c98dfc886 100644 --- a/go.mod +++ b/go.mod @@ -219,6 +219,6 @@ tool ( replace gopkg.in/yaml.v3 => github.com/andig/yaml v0.0.0-20240531135838-1ff5761ab467 -replace github.com/grid-x/modbus => github.com/evcc-io/modbus v0.0.0-20250403111054-69e330ffbd07 +replace github.com/grid-x/modbus => github.com/evcc-io/modbus v0.0.0-20250420095335-2cd088941a35 replace github.com/lorenzodonini/ocpp-go => github.com/evcc-io/ocpp-go v0.0.0-20250322092544-c0c6094051c0 diff --git a/go.sum b/go.sum index 0a12db162..861323975 100644 --- a/go.sum +++ b/go.sum @@ -155,8 +155,8 @@ github.com/enbility/zeroconf/v2 v2.0.0-20240920094356-be1cae74fda6/go.mod h1:Bsz github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evcc-io/modbus v0.0.0-20250403111054-69e330ffbd07 h1:OQNaVvgKSJabdxrQVkXANhpfsinAil1GzbOwHgghxTo= -github.com/evcc-io/modbus v0.0.0-20250403111054-69e330ffbd07/go.mod h1:swrNGAVgI1r/3d/sEKE7qgujdRR9aHVPYKyc3gvpVTc= +github.com/evcc-io/modbus v0.0.0-20250420095335-2cd088941a35 h1:OBKG6g2jjwF93LOWXrHyPBhggJkgInWMWVvA7AkCf7Q= +github.com/evcc-io/modbus v0.0.0-20250420095335-2cd088941a35/go.mod h1:swrNGAVgI1r/3d/sEKE7qgujdRR9aHVPYKyc3gvpVTc= github.com/evcc-io/ocpp-go v0.0.0-20250322092544-c0c6094051c0 h1:Qz34Pm1Wr05jjJia5g2On3zRqdZh+BLTwqHgJGsiIh4= github.com/evcc-io/ocpp-go v0.0.0-20250322092544-c0c6094051c0/go.mod h1:2kcukDdhui4u730VfnYVWuwzDLgw+mBRGDir/QAyBhg= github.com/evcc-io/rct v0.1.2-0.20250315164247-d2f41b161785 h1:OWCBVMcPsVTffdiZN3VYaq9p4fsWlzd490J6pekaKLA= diff --git a/util/modbus/functions.go b/util/modbus/functions.go index d5c0bc879..5c745896d 100644 --- a/util/modbus/functions.go +++ b/util/modbus/functions.go @@ -7,8 +7,15 @@ import ( "fmt" "strconv" "strings" + "time" + + "github.com/cenkalti/backoff/v4" ) +func Backoff() *backoff.ExponentialBackOff { + return backoff.NewExponentialBackOff(backoff.WithInitialInterval(20*time.Millisecond), backoff.WithMaxElapsedTime(5*time.Second)) +} + // decodeMask converts a bit mask in decimal or hex format to uint64 func decodeMask(mask string) (uint64, error) { mask = strings.ToLower(mask)