Ocpp: fix availability timeout (#16100)

This commit is contained in:
andig 2024-09-14 13:54:32 +02:00 • committed by GitHub
parent 624b1a81b0
commit 1273ef9ab6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 40 additions and 20 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -2,8 +2,8 @@ package charger
import (
"fmt"
"strings"
"testing"
"time"
)
type ocppLogger struct {
@ -11,17 +11,7 @@ type ocppLogger struct {
}
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...)) }