From f3be63f2d1c02dbb0d20c827de87a0e7766b29a2 Mon Sep 17 00:00:00 2001 From: andig Date: Sun, 4 Aug 2024 00:18:58 +0200 Subject: [PATCH] Ocpp: handle trigger responses (#15220) --- charger/ocpp.go | 10 +--------- charger/ocpp/connector.go | 4 ++-- charger/ocpp/cs.go | 4 +++- charger/ocpp/cs_core.go | 34 ++++++++++++++++++++++------------ charger/ocpp/helper.go | 20 ++++++++++++++++++++ charger/ocpp/instance.go | 1 + 6 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 charger/ocpp/helper.go diff --git a/charger/ocpp.go b/charger/ocpp.go index d31802d1e..c9484bd42 100644 --- a/charger/ocpp.go +++ b/charger/ocpp.go @@ -330,15 +330,7 @@ func (c *OCPP) configure(key, val string) error { // wait waits for a CP roundtrip with timeout func (c *OCPP) wait(err error, rc chan error) error { - if err == nil { - select { - case err = <-rc: - close(rc) - case <-time.After(c.timeout): - err = api.ErrTimeout - } - } - return err + return ocpp.Wait(err, rc, c.timeout) } // Status implements the api.Charger interface diff --git a/charger/ocpp/connector.go b/charger/ocpp/connector.go index 8c4459aa2..1c7e807ad 100644 --- a/charger/ocpp/connector.go +++ b/charger/ocpp/connector.go @@ -68,8 +68,8 @@ func (conn *Connector) IdTag() string { return conn.idTag } -func (conn *Connector) TriggerMessageRequest(feature remotetrigger.MessageTrigger, f ...func(request *remotetrigger.TriggerMessageRequest)) { - Instance().TriggerMessageRequest(conn.cp.ID(), feature, func(request *remotetrigger.TriggerMessageRequest) { +func (conn *Connector) TriggerMessageRequest(feature remotetrigger.MessageTrigger, f ...func(request *remotetrigger.TriggerMessageRequest)) error { + return Instance().TriggerMessageRequest(conn.cp.ID(), feature, func(request *remotetrigger.TriggerMessageRequest) { request.ConnectorId = &conn.id for _, f := range f { f(request) diff --git a/charger/ocpp/cs.go b/charger/ocpp/cs.go index 70e0d1986..84f8ff414 100644 --- a/charger/ocpp/cs.go +++ b/charger/ocpp/cs.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "sync" + "time" "github.com/evcc-io/evcc/util" ocpp16 "github.com/lorenzodonini/ocpp-go/ocpp1.6" @@ -13,7 +14,8 @@ type CS struct { mu sync.Mutex log *util.Logger ocpp16.CentralSystem - cps map[string]*CP + cps map[string]*CP + timeout time.Duration } // Register registers a charge point with the central system. diff --git a/charger/ocpp/cs_core.go b/charger/ocpp/cs_core.go index af7c82c4b..593640bc7 100644 --- a/charger/ocpp/cs_core.go +++ b/charger/ocpp/cs_core.go @@ -1,6 +1,8 @@ package ocpp import ( + "errors" + "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" "github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware" "github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger" @@ -8,24 +10,32 @@ import ( // cs actions -func (cs *CS) TriggerResetRequest(id string, resetType core.ResetType) { - if err := cs.Reset(id, func(request *core.ResetConfirmation, err error) { +func (cs *CS) TriggerResetRequest(id string, resetType core.ResetType) error { + rc := make(chan error, 1) + + err := cs.Reset(id, func(request *core.ResetConfirmation, err error) { if err == nil && request != nil && request.Status != core.ResetStatusAccepted { - cs.log.ERROR.Printf("TriggerReset for %s: %+v", id, request.Status) + err = errors.New(string(request.Status)) } - }, resetType); err != nil { - cs.log.ERROR.Printf("send TriggerReset for %s failed: %v", id, err) - } + + rc <- err + }, resetType) + + return Wait(err, rc, cs.timeout) } -func (cs *CS) TriggerMessageRequest(id string, requestedMessage remotetrigger.MessageTrigger, props ...func(request *remotetrigger.TriggerMessageRequest)) { - if err := cs.TriggerMessage(id, func(request *remotetrigger.TriggerMessageConfirmation, err error) { +func (cs *CS) TriggerMessageRequest(id string, requestedMessage remotetrigger.MessageTrigger, props ...func(request *remotetrigger.TriggerMessageRequest)) error { + rc := make(chan error, 1) + + err := cs.TriggerMessage(id, func(request *remotetrigger.TriggerMessageConfirmation, err error) { if err == nil && request != nil && request.Status != remotetrigger.TriggerMessageStatusAccepted { - cs.log.ERROR.Printf("TriggerMessage %s for %s: %+v", requestedMessage, id, request.Status) + err = errors.New(string(request.Status)) } - }, requestedMessage, props...); err != nil { - cs.log.ERROR.Printf("send TriggerMessage %s for %s failed: %v", requestedMessage, id, err) - } + + rc <- err + }, requestedMessage, props...) + + return Wait(err, rc, cs.timeout) } // cp actions diff --git a/charger/ocpp/helper.go b/charger/ocpp/helper.go new file mode 100644 index 000000000..d774c741e --- /dev/null +++ b/charger/ocpp/helper.go @@ -0,0 +1,20 @@ +package ocpp + +import ( + "time" + + "github.com/evcc-io/evcc/api" +) + +// Wait waits for a CP roundtrip with timeout +func Wait(err error, rc chan error, timeout time.Duration) error { + if err == nil { + select { + case err = <-rc: + close(rc) + case <-time.After(timeout): + err = api.ErrTimeout + } + } + return err +} diff --git a/charger/ocpp/instance.go b/charger/ocpp/instance.go index 9df9ec1ec..6ceddf7f0 100644 --- a/charger/ocpp/instance.go +++ b/charger/ocpp/instance.go @@ -49,6 +49,7 @@ func Instance() *CS { log: log, cps: make(map[string]*CP), CentralSystem: cs, + timeout: 30 * time.Second, } ocppj.SetLogger(instance)