Ocpp: fix availability timeout (#16100)
This commit is contained in:
parent
624b1a81b0
commit
1273ef9ab6
5 changed files with 40 additions and 20 deletions
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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...)) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue