Skip to content

Commit

Permalink
Ocpp: fix availability timeout (#16100)
Browse files Browse the repository at this point in the history
  • Loading branch information
andig committed Sep 14, 2024
1 parent 624b1a8 commit 1273ef9
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 20 deletions.
8 changes: 7 additions & 1 deletion charger/ocpp/helper.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package ocpp

import (
"errors"
"slices"
"strings"
"time"

"github.com/evcc-io/evcc/api"
"github.com/lorenzodonini/ocpp-go/ocpp"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/types"
"github.com/lorenzodonini/ocpp-go/ocppj"
)

// wait waits for a CP roundtrip with timeout
Expand All @@ -15,7 +18,10 @@ func wait(err error, rc chan error) error {
select {
case err = <-rc:
close(rc)
case <-time.After(Timeout):
}

oe := new(ocpp.Error)
if errors.As(err, &oe) && oe.Code == ocppj.GenericError {
err = api.ErrTimeout
}
}
Expand Down
6 changes: 1 addition & 5 deletions charger/ocpp/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,11 @@ func Instance() *CS {
once.Do(func() {
log := util.NewLogger("ocpp")

timeoutConfig := ws.NewServerTimeoutConfig()
timeoutConfig.PingWait = 90 * time.Second

server := ws.NewServer()
server.SetTimeoutConfig(timeoutConfig)
server.SetCheckOriginHandler(func(r *http.Request) bool { return true })

dispatcher := ocppj.NewDefaultServerDispatcher(ocppj.NewFIFOQueueMap(0))
dispatcher.SetTimeout(time.Minute)
dispatcher.SetTimeout(Timeout)

endpoint := ocppj.NewServer(server, dispatcher, nil, core.Profile, remotetrigger.Profile, smartcharging.Profile)
endpoint.SetInvalidMessageHook(func(client ws.Channel, err *ocpp.Error, rawMessage string, parsedFields []interface{}) *ocpp.Error {
Expand Down
25 changes: 23 additions & 2 deletions charger/ocpp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,21 @@ type ocppTestSuite struct {
}

func (suite *ocppTestSuite) SetupSuite() {
ocpp.Timeout = 5 * time.Second

// setup cs so we can overwrite logger afterwards
_ = ocpp.Instance()
ocppj.SetLogger(&ocppLogger{suite.T()})

ocpp.Timeout = 5 * time.Second

suite.clock = clock.NewMock()
suite.NotNil(ocpp.Instance())
}

func (suite *ocppTestSuite) SetupTest() {
// default delays
ocppDelays = make(map[string]time.Duration)
}

func (suite *ocppTestSuite) startChargePoint(id string, connectorId int) ocpp16.ChargePoint {
// set a handler for all callback functions
handler := &ChargePointHandler{
Expand Down Expand Up @@ -223,3 +228,19 @@ func (suite *ocppTestSuite) TestAutoStart() {
err = c1.Enable(false)
suite.Require().NoError(err)
}

func (suite *ocppTestSuite) TestTimeout() {
// 1st charge point- remote
cp1 := suite.startChargePoint("test-4", 1)
suite.Require().NoError(cp1.Start(ocppTestUrl))
suite.Require().True(cp1.IsConnected())

// timeout change availability request
ocppDelays[core.ChangeAvailabilityFeatureName] = time.Minute

// 1st charge point- local
_, err := NewOCPP("test-4", 1, "", "", 0, false, false, ocppTestConnectTimeout)

// TODO fix test - this should NOT error
suite.Require().Error(err)
}
7 changes: 7 additions & 0 deletions charger/ocpp_test_handler.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package charger

import (
"time"

"github.com/lorenzodonini/ocpp-go/ocpp1.6/core"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging"
Expand All @@ -11,10 +13,15 @@ type ChargePointHandler struct {
triggerC chan remotetrigger.MessageTrigger
}

var ocppDelays = make(map[string]time.Duration)

// core

func (handler *ChargePointHandler) OnChangeAvailability(request *core.ChangeAvailabilityRequest) (confirmation *core.ChangeAvailabilityConfirmation, err error) {
defer func() { handler.triggerC <- core.ChangeAvailabilityFeatureName }()
if d, ok := ocppDelays[core.ChangeAvailabilityFeatureName]; ok {
time.Sleep(d)
}
return core.NewChangeAvailabilityConfirmation(core.AvailabilityStatusAccepted), nil
}

Expand Down
14 changes: 2 additions & 12 deletions charger/ocpp_test_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,16 @@ package charger

import (
"fmt"
"strings"
"testing"
"time"
)

type ocppLogger struct {
t *testing.T
}

func print(t *testing.T, s string) {
var ok bool
if s, ok = strings.CutPrefix(s, "sent JSON message to"); ok {
s = "send" + s
} else if s, ok = strings.CutPrefix(s, "received JSON message from"); ok {
s = "recv" + s
} else {
ok = true
}
if ok {
t.Log(s)
}
t.Log((time.Now().Format(time.DateTime)), s)
}

func (l *ocppLogger) Debug(args ...interface{}) { print(l.t, fmt.Sprint(args...)) }
Expand Down

0 comments on commit 1273ef9

Please sign in to comment.