Modbus: increase timeout and backoff (#20730)

This commit is contained in:
andig 2025-04-20 12:24:37 +02:00 • committed by GitHub
parent 7f075adad9
commit 12d8e448ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 19 additions and 28 deletions

View file

@ -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)
}

View file

@ -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))
}

View file

@ -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 {

View file

@ -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)
}
}

View file

@ -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)

2
go.mod
View file

@ -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

4
go.sum
View file

@ -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=

View file

@ -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)