diff --git a/charger/ocpp/helper.go b/charger/ocpp/helper.go index db16d9a90..da86760f9 100644 --- a/charger/ocpp/helper.go +++ b/charger/ocpp/helper.go @@ -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 } } diff --git a/charger/ocpp/instance.go b/charger/ocpp/instance.go index 94624a367..4220fc50c 100644 --- a/charger/ocpp/instance.go +++ b/charger/ocpp/instance.go @@ -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 { diff --git a/charger/ocpp_test.go b/charger/ocpp_test.go index ce6efe4c6..6aef283c8 100644 --- a/charger/ocpp_test.go +++ b/charger/ocpp_test.go @@ -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) +} diff --git a/charger/ocpp_test_handler.go b/charger/ocpp_test_handler.go index 1069dedb0..0ef2abb97 100644 --- a/charger/ocpp_test_handler.go +++ b/charger/ocpp_test_handler.go @@ -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 } diff --git a/charger/ocpp_test_logger.go b/charger/ocpp_test_logger.go index 8fad7e12e..ab6618a99 100644 --- a/charger/ocpp_test_logger.go +++ b/charger/ocpp_test_logger.go @@ -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...)) }