Ocpp: use context (#19282)
This commit is contained in:
parent
1cafc24627
commit
766194d0c0
4 changed files with 32 additions and 14 deletions
|
|
@ -19,6 +19,7 @@ package charger
|
|||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"slices"
|
||||
|
|
@ -50,11 +51,11 @@ type OCPP struct {
|
|||
const defaultIdTag = "evcc" // RemoteStartTransaction only
|
||||
|
||||
func init() {
|
||||
registry.Add("ocpp", NewOCPPFromConfig)
|
||||
registry.AddCtx("ocpp", NewOCPPFromConfig)
|
||||
}
|
||||
|
||||
// NewOCPPFromConfig creates a OCPP charger from generic config
|
||||
func NewOCPPFromConfig(other map[string]interface{}) (api.Charger, error) {
|
||||
func NewOCPPFromConfig(ctx context.Context, other map[string]interface{}) (api.Charger, error) {
|
||||
cc := struct {
|
||||
StationId string
|
||||
IdTag string
|
||||
|
|
@ -84,7 +85,8 @@ func NewOCPPFromConfig(other map[string]interface{}) (api.Charger, error) {
|
|||
|
||||
stackLevelZero := cc.StackLevelZero != nil && *cc.StackLevelZero
|
||||
|
||||
c, err := NewOCPP(cc.StationId, cc.Connector, cc.IdTag,
|
||||
c, err := NewOCPP(ctx,
|
||||
cc.StationId, cc.Connector, cc.IdTag,
|
||||
cc.MeterValues, cc.MeterInterval,
|
||||
stackLevelZero, cc.RemoteStart,
|
||||
cc.ConnectTimeout)
|
||||
|
|
@ -137,7 +139,8 @@ func NewOCPPFromConfig(other map[string]interface{}) (api.Charger, error) {
|
|||
//go:generate go tool decorate -f decorateOCPP -b *OCPP -r api.Charger -t "api.Meter,CurrentPower,func() (float64, error)" -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.PhaseCurrents,Currents,func() (float64, float64, float64, error)" -t "api.PhaseVoltages,Voltages,func() (float64, float64, float64, error)" -t "api.CurrentGetter,GetMaxCurrent,func() (float64, error)" -t "api.PhaseSwitcher,Phases1p3p,func(int) error" -t "api.Battery,Soc,func() (float64, error)"
|
||||
|
||||
// NewOCPP creates OCPP charger
|
||||
func NewOCPP(id string, connector int, idTag string,
|
||||
func NewOCPP(ctx context.Context,
|
||||
id string, connector int, idTag string,
|
||||
meterValues string, meterInterval time.Duration,
|
||||
stackLevelZero, remoteStart bool,
|
||||
connectTimeout time.Duration,
|
||||
|
|
@ -154,12 +157,14 @@ func NewOCPP(id string, connector int, idTag string,
|
|||
log.DEBUG.Printf("waiting for chargepoint: %v", connectTimeout)
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-time.After(connectTimeout):
|
||||
return api.ErrTimeout
|
||||
case <-cp.HasConnected():
|
||||
}
|
||||
|
||||
return cp.Setup(meterValues, meterInterval)
|
||||
return cp.Setup(ctx, meterValues, meterInterval)
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -188,7 +193,9 @@ func NewOCPP(id string, connector int, idTag string,
|
|||
stackLevelZero: stackLevelZero,
|
||||
}
|
||||
|
||||
go conn.WatchDog(10 * time.Second)
|
||||
if cp.HasRemoteTriggerFeature {
|
||||
go conn.WatchDog(ctx, 10*time.Second)
|
||||
}
|
||||
|
||||
return c, conn.Initialized()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package ocpp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -100,16 +101,22 @@ func (conn *Connector) GetScheduleLimit(duration int) (float64, error) {
|
|||
|
||||
// WatchDog triggers meter values messages if older than timeout.
|
||||
// Must be wrapped in a goroutine.
|
||||
func (conn *Connector) WatchDog(timeout time.Duration) {
|
||||
func (conn *Connector) WatchDog(ctx context.Context, timeout time.Duration) {
|
||||
tick := time.NewTicker(2 * time.Second)
|
||||
for ; true; <-tick.C {
|
||||
for {
|
||||
conn.mu.Lock()
|
||||
update := conn.clock.Since(conn.meterUpdated) > timeout
|
||||
conn.mu.Unlock()
|
||||
|
||||
if update && conn.cp.HasRemoteTriggerFeature {
|
||||
if update {
|
||||
conn.TriggerMessageRequest(core.MeterValuesFeatureName)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-tick.C:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package ocpp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -12,7 +13,7 @@ import (
|
|||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func (cp *CP) Setup(meterValues string, meterInterval time.Duration) error {
|
||||
func (cp *CP) Setup(ctx context.Context, meterValues string, meterInterval time.Duration) error {
|
||||
if err := cp.ChangeAvailabilityRequest(0, core.AvailabilityTypeOperative); err != nil {
|
||||
cp.log.DEBUG.Printf("failed configuring availability: %v", err)
|
||||
}
|
||||
|
|
@ -136,6 +137,8 @@ func (cp *CP) Setup(meterValues string, meterInterval time.Duration) error {
|
|||
if err := cp.TriggerMessageRequest(0, core.MeterValuesFeatureName); err == nil {
|
||||
// wait for meter values
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-time.After(Timeout):
|
||||
cp.log.WARN.Println("meter timeout")
|
||||
case <-cp.meterC:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package charger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -112,7 +113,7 @@ func (suite *ocppTestSuite) TestConnect() {
|
|||
suite.Require().True(cp1.IsConnected())
|
||||
|
||||
// 1st charge point- local
|
||||
c1, err := NewOCPP("test-1", 1, "", "", 0, false, true, ocppTestConnectTimeout)
|
||||
c1, err := NewOCPP(context.TODO(), "test-1", 1, "", "", 0, false, true, ocppTestConnectTimeout)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// status and meter values
|
||||
|
|
@ -161,7 +162,7 @@ func (suite *ocppTestSuite) TestConnect() {
|
|||
suite.Require().True(cp2.IsConnected())
|
||||
|
||||
// 2nd charge point - local
|
||||
c2, err := NewOCPP("test-2", 1, "", "", 0, false, true, ocppTestConnectTimeout)
|
||||
c2, err := NewOCPP(context.TODO(), "test-2", 1, "", "", 0, false, true, ocppTestConnectTimeout)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
{
|
||||
|
|
@ -203,7 +204,7 @@ func (suite *ocppTestSuite) TestAutoStart() {
|
|||
suite.Require().True(cp1.IsConnected())
|
||||
|
||||
// 1st charge point- local
|
||||
c1, err := NewOCPP("test-3", 1, "", "", 0, false, false, ocppTestConnectTimeout)
|
||||
c1, err := NewOCPP(context.TODO(), "test-3", 1, "", "", 0, false, false, ocppTestConnectTimeout)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// status and meter values
|
||||
|
|
@ -250,7 +251,7 @@ func (suite *ocppTestSuite) TestTimeout() {
|
|||
})
|
||||
|
||||
// 1st charge point- local
|
||||
_, err := NewOCPP("test-4", 1, "", "", 0, false, false, ocppTestConnectTimeout)
|
||||
_, err := NewOCPP(context.TODO(), "test-4", 1, "", "", 0, false, false, ocppTestConnectTimeout)
|
||||
|
||||
suite.Require().NoError(err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue