From ec8c7631064094f74ad664c657db69000b5ec884 Mon Sep 17 00:00:00 2001 From: andig Date: Fri, 17 Mar 2023 17:32:28 +0100 Subject: [PATCH] Ocpp: split connection and runtime timeouts (#6898) --- charger/ocpp.go | 23 ++++++++++++++++------- charger/ocpp/cp.go | 11 ++++++----- templates/docs/charger/elvi_0.yaml | 3 ++- templates/docs/charger/ocpp_0.yaml | 3 ++- templates/docs/charger/pulsarplus_0.yaml | 3 ++- util/templates/defaults.yaml | 9 ++++++++- util/templates/includes/ocpp.tpl | 1 + 7 files changed, 37 insertions(+), 16 deletions(-) diff --git a/charger/ocpp.go b/charger/ocpp.go index a2877ed816..b38605ba13 100644 --- a/charger/ocpp.go +++ b/charger/ocpp.go @@ -47,6 +47,7 @@ func NewOCPPFromConfig(other map[string]interface{}) (api.Charger, error) { Connector int MeterInterval time.Duration MeterValues string + ConnectTimeout time.Duration Timeout time.Duration BootNotification *bool GetConfiguration *bool @@ -54,9 +55,10 @@ func NewOCPPFromConfig(other map[string]interface{}) (api.Charger, error) { Quirks interface{} // TODO deprecated InitialReset interface{} // TODO deprecated }{ - Connector: 1, - IdTag: defaultIdTag, - Timeout: time.Minute, + Connector: 1, + IdTag: defaultIdTag, + ConnectTimeout: 2 * time.Minute, + Timeout: 2 * time.Minute, } if err := util.DecodeOther(other, &cc); err != nil { @@ -75,7 +77,10 @@ func NewOCPPFromConfig(other map[string]interface{}) (api.Charger, error) { boot := cc.BootNotification != nil && *cc.BootNotification noConfig := cc.GetConfiguration != nil && !*cc.GetConfiguration - c, err := NewOCPP(cc.StationId, cc.Connector, cc.IdTag, cc.MeterValues, cc.MeterInterval, boot, noConfig, cc.Timeout) + c, err := NewOCPP(cc.StationId, cc.Connector, cc.IdTag, + cc.MeterValues, cc.MeterInterval, + boot, noConfig, + cc.ConnectTimeout, cc.Timeout) if err != nil { return c, err } @@ -106,7 +111,11 @@ func NewOCPPFromConfig(other map[string]interface{}) (api.Charger, error) { // go:generate go run ../cmd/tools/decorate.go -f decorateOCPP -b *OCPP -r api.Charger -t "api.Meter,CurrentPower,func() (float64, error)" -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.PhaseCurrents,Currents,func() (float64, float64, float64, error)" -t "api.PhaseSwitcher,Phases1p3p,func(int) (error)" // NewOCPP creates OCPP charger -func NewOCPP(id string, connector int, idtag string, meterValues string, meterInterval time.Duration, boot, noConfig bool, timeout time.Duration) (*OCPP, error) { +func NewOCPP(id string, connector int, idtag string, + meterValues string, meterInterval time.Duration, + boot, noConfig bool, + connectTimeout, timeout time.Duration, +) (*OCPP, error) { unit := "ocpp" if id != "" { unit = id @@ -126,10 +135,10 @@ func NewOCPP(id string, connector int, idtag string, meterValues string, meterIn timeout: timeout, } - c.log.DEBUG.Printf("waiting for chargepoint: %v", timeout) + c.log.DEBUG.Printf("waiting for chargepoint: %v", connectTimeout) select { - case <-time.After(timeout): + case <-time.After(connectTimeout): return nil, api.ErrTimeout case <-cp.HasConnected(): } diff --git a/charger/ocpp/cp.go b/charger/ocpp/cp.go index 119217bc43..ab732cc717 100644 --- a/charger/ocpp/cp.go +++ b/charger/ocpp/cp.go @@ -44,11 +44,12 @@ type CP struct { connector int connectC, statusC chan struct{} - updated time.Time status *core.StatusNotificationRequest - timeout time.Duration + updated time.Time meterUpdated time.Time + timeout time.Duration + measurements map[string]types.SampledValue txnCount int // change initial value to the last known global transaction. Needs persistence @@ -184,7 +185,7 @@ func (cp *CP) CurrentPower() (float64, error) { cp.mu.Lock() defer cp.mu.Unlock() - if cp.timeout > 0 && time.Since(cp.meterUpdated) > cp.timeout { + if cp.txnId != 0 && cp.timeout > 0 && time.Since(cp.meterUpdated) > cp.timeout { return 0, api.ErrNotAvailable } @@ -202,7 +203,7 @@ func (cp *CP) TotalEnergy() (float64, error) { cp.mu.Lock() defer cp.mu.Unlock() - if cp.timeout > 0 && time.Since(cp.meterUpdated) > cp.timeout { + if cp.txnId != 0 && cp.timeout > 0 && time.Since(cp.meterUpdated) > cp.timeout { return 0, api.ErrNotAvailable } @@ -235,7 +236,7 @@ func (cp *CP) Currents() (float64, float64, float64, error) { cp.mu.Lock() defer cp.mu.Unlock() - if cp.timeout > 0 && time.Since(cp.meterUpdated) > cp.timeout { + if cp.txnId != 0 && cp.timeout > 0 && time.Since(cp.meterUpdated) > cp.timeout { return 0, 0, 0, api.ErrNotAvailable } diff --git a/templates/docs/charger/elvi_0.yaml b/templates/docs/charger/elvi_0.yaml index b62e74b7ab..93d0fa366b 100644 --- a/templates/docs/charger/elvi_0.yaml +++ b/templates/docs/charger/elvi_0.yaml @@ -11,4 +11,5 @@ render: stationid: EVB-P12354 # Die Stations-ID der Wallbox (oder des Ladepunkts) # Optional connector: 1 # Ladepunkt, normalerweise 1 für den ersten Anschluss. # Optional idtag: '04E6B78921BBA0' # Token-ID welche für die Freischaltung der Ladevorgänge an den Ladepunkt zurückgesendet wird # Optional - timeout: 10m # Optional + connecttimeout: 5m # Optional + timeout: 2m # Optional diff --git a/templates/docs/charger/ocpp_0.yaml b/templates/docs/charger/ocpp_0.yaml index 81b54e2071..013e72c72f 100644 --- a/templates/docs/charger/ocpp_0.yaml +++ b/templates/docs/charger/ocpp_0.yaml @@ -26,6 +26,7 @@ render: stationid: EVB-P12354 # Die Stations-ID der Wallbox (oder des Ladepunkts) # Optional connector: 1 # Ladepunkt, normalerweise 1 für den ersten Anschluss. # Optional idtag: '04E6B78921BBA0' # Token-ID welche für die Freischaltung der Ladevorgänge an den Ladepunkt zurückgesendet wird # Optional - timeout: 10m # Optional + connecttimeout: 5m # Optional + timeout: 2m # Optional getconfiguration: true # Deaktivierung kann bei einigen Chargern hilfreich sein # Optional bootnotification: false # Aktivierung kann bei einigen Chargern hilfreich sein # Optional diff --git a/templates/docs/charger/pulsarplus_0.yaml b/templates/docs/charger/pulsarplus_0.yaml index 8eb15c17a6..5c91d84808 100644 --- a/templates/docs/charger/pulsarplus_0.yaml +++ b/templates/docs/charger/pulsarplus_0.yaml @@ -11,4 +11,5 @@ render: stationid: EVB-P12354 # Die Stations-ID der Wallbox (oder des Ladepunkts) # Optional connector: 1 # Ladepunkt, normalerweise 1 für den ersten Anschluss. # Optional idtag: '04E6B78921BBA0' # Token-ID welche für die Freischaltung der Ladevorgänge an den Ladepunkt zurückgesendet wird # Optional - timeout: 10m # Optional + connecttimeout: 5m # Optional + timeout: 2m # Optional diff --git a/util/templates/defaults.yaml b/util/templates/defaults.yaml index f80d3ea207..4a0f449cd5 100644 --- a/util/templates/defaults.yaml +++ b/util/templates/defaults.yaml @@ -363,8 +363,15 @@ presets: de: Token-ID welche für die Freischaltung der Ladevorgänge an den Ladepunkt zurückgesendet wird advanced: true example: 04E6B78921BBA0 + - name: connecttimeout + description: + de: Zeitlimit für Registrierung des Ladepunktes + en: Timeout for initial connection + advanced: true + type: duration + default: 5m - name: timeout - default: 10m + default: 2m mqtt: params: diff --git a/util/templates/includes/ocpp.tpl b/util/templates/includes/ocpp.tpl index b78f0f4c02..02dc279f90 100644 --- a/util/templates/includes/ocpp.tpl +++ b/util/templates/includes/ocpp.tpl @@ -9,5 +9,6 @@ connector: {{ .connector }} {{- if ne .idtag "" }} idtag: {{ .idtag }} {{- end }} +connecttimeout: {{ .connecttimeout }} timeout: {{ .timeout }} {{- end }}