Em2go: improve connection robustness (#29351)
This commit is contained in:
parent
35b033324b
commit
67588c2d66
2 changed files with 60 additions and 1 deletions
|
|
@ -101,9 +101,32 @@ func NewEm2GoDuo(ctx context.Context, uri string, slaveID uint8, connector int)
|
|||
connector: connector,
|
||||
}
|
||||
|
||||
b, err := wb.conn.ReadHoldingRegisters(em2GoDuoRegCommTimeout, 1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failsafe timeout: %w", err)
|
||||
}
|
||||
if u := binary.BigEndian.Uint16(b); u > 0 {
|
||||
go wb.heartbeat(ctx, time.Duration(u)*time.Second/2)
|
||||
}
|
||||
|
||||
return wb, nil
|
||||
}
|
||||
|
||||
// heartbeat keeps the Modbus connection alive to prevent the charger from
|
||||
// entering its failsafe state when the configured communication timeout expires.
|
||||
func (wb *Em2GoDuo) heartbeat(ctx context.Context, interval time.Duration) {
|
||||
for tick := time.Tick(interval); ; {
|
||||
select {
|
||||
case <-tick:
|
||||
if _, err := wb.conn.ReadHoldingRegisters(em2GoDuoRegSafeCurrent, 1); err != nil {
|
||||
wb.log.ERROR.Println("heartbeat:", err)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Status implements the api.Charger interface
|
||||
func (wb *Em2GoDuo) Status() (api.ChargeStatus, error) {
|
||||
b, err := wb.conn.ReadHoldingRegisters(em2GoDuoRegConnectorState, 1)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/modbus"
|
||||
|
|
@ -108,7 +109,42 @@ func NewEm2Go(ctx context.Context, uri string, slaveID uint8) (api.Charger, erro
|
|||
current: 60,
|
||||
}
|
||||
|
||||
return wb.initialize()
|
||||
bo := backoff.WithContext(
|
||||
backoff.NewExponentialBackOff(
|
||||
backoff.WithInitialInterval(2*time.Second),
|
||||
backoff.WithMaxInterval(10*time.Second),
|
||||
backoff.WithMaxElapsedTime(30*time.Second),
|
||||
), ctx)
|
||||
|
||||
res, err := backoff.RetryWithData(wb.initialize, bo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b, err := wb.conn.ReadHoldingRegisters(em2GoRegCommTimeout, 1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failsafe timeout: %w", err)
|
||||
}
|
||||
if u := binary.BigEndian.Uint16(b); u > 0 {
|
||||
go wb.heartbeat(ctx, time.Duration(u)*time.Second/2)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// heartbeat keeps the Modbus connection alive to prevent the charger from
|
||||
// entering its failsafe state when the configured communication timeout expires.
|
||||
func (wb *Em2Go) heartbeat(ctx context.Context, interval time.Duration) {
|
||||
for tick := time.Tick(interval); ; {
|
||||
select {
|
||||
case <-tick:
|
||||
if _, err := wb.conn.ReadHoldingRegisters(em2GoRegSafeCurrent, 1); err != nil {
|
||||
wb.log.ERROR.Println("heartbeat:", err)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialize performs common initialization for both Em2Go models
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue