From 62dd3a41561417ff22f7a92a4d2f79a662ef68fa Mon Sep 17 00:00:00 2001 From: andig Date: Sun, 12 Mar 2023 10:56:46 +0100 Subject: [PATCH] Ocpp: improve configuration and compatibility (#6785) --- charger/ocpp.go | 37 ++++++----- templates/definition/charger/ocpp-elvi.yaml | 10 +++ .../definition/charger/ocpp-pulsarplus.yaml | 10 +++ templates/definition/charger/ocpp.yaml | 61 +++++++++---------- templates/docs/charger/elvi_0.yaml | 14 +++++ templates/docs/charger/ocpp_0.yaml | 10 +-- templates/docs/charger/pulsarplus_0.yaml | 14 +++++ templates/docs/meter/sma-energy-meter_0.yaml | 4 +- templates/docs/meter/sma-home-manager_0.yaml | 2 +- templates/evcc.io/brands.json | 2 + util/templates/defaults.yaml | 28 ++++++++- util/templates/includes/ocpp.tpl | 13 ++++ 12 files changed, 148 insertions(+), 57 deletions(-) create mode 100644 templates/definition/charger/ocpp-elvi.yaml create mode 100644 templates/definition/charger/ocpp-pulsarplus.yaml create mode 100644 templates/docs/charger/elvi_0.yaml create mode 100644 templates/docs/charger/pulsarplus_0.yaml create mode 100644 util/templates/includes/ocpp.tpl diff --git a/charger/ocpp.go b/charger/ocpp.go index 5cb32c7ae..9b35a3432 100644 --- a/charger/ocpp.go +++ b/charger/ocpp.go @@ -42,15 +42,17 @@ func init() { // NewOCPPFromConfig creates a OCPP charger from generic config func NewOCPPFromConfig(other map[string]interface{}) (api.Charger, error) { cc := struct { - StationId string - IdTag string - Connector int - Meter interface{} // TODO deprecated - Quirks bool - MeterInterval time.Duration - MeterValues string - InitialReset interface{} // TODO deprecated - Timeout time.Duration + StationId string + IdTag string + Connector int + MeterInterval time.Duration + MeterValues string + Timeout time.Duration + BootNotification *bool + GetConfiguration *bool + Meter interface{} // TODO deprecated + Quirks interface{} // TODO deprecated + InitialReset interface{} // TODO deprecated }{ Connector: 1, IdTag: defaultIdTag, @@ -70,7 +72,10 @@ func NewOCPPFromConfig(other map[string]interface{}) (api.Charger, error) { // return nil, fmt.Errorf("unknown configuration option detected for reset: %s", cc.InitialReset) // } - c, err := NewOCPP(cc.StationId, cc.Connector, cc.IdTag, cc.MeterValues, cc.MeterInterval, cc.Quirks, cc.Timeout) + 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) if err != nil { return c, err } @@ -101,7 +106,7 @@ 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, quirks bool, timeout time.Duration) (*OCPP, error) { +func NewOCPP(id string, connector int, idtag string, meterValues string, meterInterval time.Duration, boot, noConfig bool, timeout time.Duration) (*OCPP, error) { unit := "ocpp" if id != "" { unit = id @@ -130,7 +135,9 @@ func NewOCPP(id string, connector int, idtag string, meterValues string, meterIn } // see who's there - // ocpp.Instance().TriggerMessageRequest(cp.ID(), core.BootNotificationFeatureName) + if boot { + ocpp.Instance().TriggerMessageRequest(cp.ID(), core.BootNotificationFeatureName) + } var ( rc = make(chan error, 1) @@ -145,8 +152,8 @@ func NewOCPP(id string, connector int, idtag string, meterValues string, meterIn } _ = keys - // quirks mode disables GetConfiguration - if quirks { + // noConfig mode disables GetConfiguration + if noConfig { c.meterValuesSample = meterValues if meterInterval == 0 { meterInterval = 10 * time.Second @@ -230,7 +237,7 @@ func NewOCPP(id string, connector int, idtag string, meterValues string, meterIn if c.hasMeasurement("Power.Active.Import") || c.hasMeasurement("Energy.Active.Import.Register") { ocpp.Instance().TriggerMessageRequest(cp.ID(), core.MeterValuesFeatureName) - if !quirks && meterSampleInterval > meterInterval && meterInterval > 0 { + if !noConfig && meterSampleInterval > meterInterval && meterInterval > 0 { if err := c.configure(ocpp.KeyMeterValueSampleInterval, strconv.Itoa(int(meterInterval.Seconds()))); err != nil { return nil, err } diff --git a/templates/definition/charger/ocpp-elvi.yaml b/templates/definition/charger/ocpp-elvi.yaml new file mode 100644 index 000000000..be6782419 --- /dev/null +++ b/templates/definition/charger/ocpp-elvi.yaml @@ -0,0 +1,10 @@ +template: elvi +products: + - brand: EVBox + description: + generic: Elvi +params: + - preset: ocpp +render: | + type: ocpp + {{ include "ocpp" . }} diff --git a/templates/definition/charger/ocpp-pulsarplus.yaml b/templates/definition/charger/ocpp-pulsarplus.yaml new file mode 100644 index 000000000..583ac691d --- /dev/null +++ b/templates/definition/charger/ocpp-pulsarplus.yaml @@ -0,0 +1,10 @@ +template: pulsarplus +products: + - brand: wallbox + description: + generic: Pulsar Plus/ Commander 2/ Copper SB +params: + - preset: ocpp +render: | + type: ocpp + {{ include "ocpp" . }} diff --git a/templates/definition/charger/ocpp.yaml b/templates/definition/charger/ocpp.yaml index 12c64d2ea..7d6f2dc67 100644 --- a/templates/definition/charger/ocpp.yaml +++ b/templates/definition/charger/ocpp.yaml @@ -2,21 +2,21 @@ template: ocpp products: - description: de: OCPP 1.6J kompatible Wallbox mit Smart Charging Profil - en: OCPP 1.6J compatible charger with smart charging profile + en: OCPP 1.6J compatible charger with Smart Charging Profile group: generic requirements: description: de: | Bei OCPP verbindet sich die Wallbox (Client) zu evcc (Server). Die Wallbox muss daher evcc via Hostname (funktionierende DNS-Auflösung erforderlich!) oder über die IP-Adresse auf Port 8887 erreichen können. - Standardmäßig wird die erste eingehende Verbindung mit einer beliebigen Ladepunkt-Kennung verwendet. + Standardmäßig wird die erste eingehende Verbindung mit einer beliebigen Ladepunktkennung verwendet. Um mehrere Ladepunkte eindeutig zuordnen zu können müssen die jeweilige Stationskennung (`stationid: `) und Anschlussnummer (`connector: `) hinterlegt werden. Gegebenenfalls benötigt der Ladepunkt eine vorkonfigurierte (virtuelle) Token-ID/RFID-Kennung (`idtag: `) mit der die Ladevorgänge ohne Authentifizierung gestartet werden können. Für Zählermesswerte sollte in der Wallbox ein kurzes Zeitintervall konfiguriert werden. Voraussetzungen: - * Ggf. zuvor konfigurierte OCPP-Profile (z.B. durch eine andere Backend-Anbindung) in der Wallbox-Konfiguration entfernen - * Backend-URL (Central System) in der Wallbox-Konfiguration: `ws://:8887/` + * Ggf. zuvor konfigurierte OCPP-Profile (z.B. durch eine andere Backend-Anbindung) in der Wallboxkonfiguration entfernen + * Backend-URL (Central System) in der Wallboxkonfiguration: `ws://:8887/` * Protokoll: OCPP-J v1.6, ocpp16j, JSON, Websocket, ws:// o.ä. * Keine Verschlüsselung, keine Authentifizierung, kein Passwort * Verbindung über das lokale Netzwerk @@ -25,8 +25,8 @@ requirements: The charger needs to be able to reach evcc via the host name (functioning DNS resolution required!) or via the IP address on port 8887. By default, the first incoming connection with any station identifier is used. In order to be able to clearly assign several charging points, the respective station identifier (`stationid: `) and connector number (`connector: `) must be configured. - The charger may need a preconfigured (virtual) token ID/RFID identifier (`idtag: `) with which the charging sessions can be started without authorization. - If the charger supports sending metering values try to adjust the interval to a short timespan. + The charger may need a pre-configured (virtual) token ID/RFID identifier (`idtag: `) with which the charging sessions can be started without authorization. + If the charger supports sending metering values try to adjust the interval to a short time span. Requirements: * If necessary, remove previously configured OCPP profiles (e.g. used for a different backend connection) in the charger configuration @@ -35,38 +35,33 @@ requirements: * No encryption, no authentication, no password * Local network connection params: - - name: stationid - type: string + - preset: ocpp + - name: getconfiguration advanced: true + type: bool + default: true + description: + de: GetConfiguration benutzen + en: Use GetConfiguration request help: - en: The chargers unique station id (or chargepoint id) - de: Die Stations-ID der Wallbox (oder des Ladepunkts) - example: EVB-P12354 - - name: connector - default: 1 - type: number + de: Deaktivierung kann bei einigen Chargern hilfreich sein + en: Deactivating can help with certain chargers + - name: bootnotification advanced: true + type: bool + default: false + description: + de: BootNotification benutzen + en: Use BootNotification request help: - en: Connector number, usually 1 for first connector. - de: Verwendeter Ladepunkt, normalerweise 1 für den ersten Anschluss. - - name: idtag - type: string - advanced: true - help: - en: Token-ID returned to the charger for authorisation of charging sessions - de: Token-ID welche für die Freischaltung der Ladevorgänge an den Ladepunkt zurückgesendet wird - example: 04E6B78921BBA0 - - name: timeout - default: 10m + de: Aktivierung kann bei einigen Chargern hilfreich sein + en: Activating can help with certain chargers render: | type: ocpp - {{- if ne .stationid "" }} - stationid: {{ .stationid }} + {{ include "ocpp" . }} + {{- if ne .getconfiguration "true" }} + getconfiguration: {{ .getconfiguration }} {{- end }} - {{- if ne .connector "1"}} - connector: {{ .connector }} + {{- if ne .bootnotification "false" }} + bootnotification: {{ .bootnotification }} {{- end }} - {{- if ne .idtag "" }} - idtag: {{ .idtag }} - {{- end }} - timeout: {{ .timeout }} diff --git a/templates/docs/charger/elvi_0.yaml b/templates/docs/charger/elvi_0.yaml new file mode 100644 index 000000000..b62e74b7a --- /dev/null +++ b/templates/docs/charger/elvi_0.yaml @@ -0,0 +1,14 @@ +product: + brand: EVBox + description: Elvi +render: + - default: | + type: template + template: elvi + advanced: | + type: template + template: elvi + 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 diff --git a/templates/docs/charger/ocpp_0.yaml b/templates/docs/charger/ocpp_0.yaml index 3c7ba848d..81b54e207 100644 --- a/templates/docs/charger/ocpp_0.yaml +++ b/templates/docs/charger/ocpp_0.yaml @@ -4,14 +4,14 @@ product: description: | Bei OCPP verbindet sich die Wallbox (Client) zu evcc (Server). Die Wallbox muss daher evcc via Hostname (funktionierende DNS-Auflösung erforderlich!) oder über die IP-Adresse auf Port 8887 erreichen können. - Standardmäßig wird die erste eingehende Verbindung mit einer beliebigen Ladepunkt-Kennung verwendet. + Standardmäßig wird die erste eingehende Verbindung mit einer beliebigen Ladepunktkennung verwendet. Um mehrere Ladepunkte eindeutig zuordnen zu können müssen die jeweilige Stationskennung (`stationid: `) und Anschlussnummer (`connector: `) hinterlegt werden. Gegebenenfalls benötigt der Ladepunkt eine vorkonfigurierte (virtuelle) Token-ID/RFID-Kennung (`idtag: `) mit der die Ladevorgänge ohne Authentifizierung gestartet werden können. Für Zählermesswerte sollte in der Wallbox ein kurzes Zeitintervall konfiguriert werden. Voraussetzungen: - * Ggf. zuvor konfigurierte OCPP-Profile (z.B. durch eine andere Backend-Anbindung) in der Wallbox-Konfiguration entfernen - * Backend-URL (Central System) in der Wallbox-Konfiguration: `ws://:8887/` + * Ggf. zuvor konfigurierte OCPP-Profile (z.B. durch eine andere Backend-Anbindung) in der Wallboxkonfiguration entfernen + * Backend-URL (Central System) in der Wallboxkonfiguration: `ws://:8887/` * Protokoll: OCPP-J v1.6, ocpp16j, JSON, Websocket, ws:// o.ä. * Keine Verschlüsselung, keine Authentifizierung, kein Passwort * Verbindung über das lokale Netzwerk @@ -24,6 +24,8 @@ render: type: template template: ocpp stationid: EVB-P12354 # Die Stations-ID der Wallbox (oder des Ladepunkts) # Optional - connector: 1 # Verwendeter Ladepunkt, normalerweise 1 für den ersten Anschluss. # 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 + 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 new file mode 100644 index 000000000..8eb15c17a --- /dev/null +++ b/templates/docs/charger/pulsarplus_0.yaml @@ -0,0 +1,14 @@ +product: + brand: wallbox + description: Pulsar Plus/ Commander 2/ Copper SB +render: + - default: | + type: template + template: pulsarplus + advanced: | + type: template + template: pulsarplus + 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 diff --git a/templates/docs/meter/sma-energy-meter_0.yaml b/templates/docs/meter/sma-energy-meter_0.yaml index fa9905123..9154b995c 100644 --- a/templates/docs/meter/sma-energy-meter_0.yaml +++ b/templates/docs/meter/sma-energy-meter_0.yaml @@ -13,7 +13,7 @@ render: template: sma-energy-meter usage: grid host: 192.0.2.2 # IP-Adresse oder Hostname - interface: eth0 # Netzwerkinterface # Optional + interface: eth0 # Netzwerkschnittstelle # Optional - usage: pv default: | type: template @@ -25,4 +25,4 @@ render: template: sma-energy-meter usage: pv host: 192.0.2.2 # IP-Adresse oder Hostname - interface: eth0 # Netzwerkinterface # Optional + interface: eth0 # Netzwerkschnittstelle # Optional diff --git a/templates/docs/meter/sma-home-manager_0.yaml b/templates/docs/meter/sma-home-manager_0.yaml index f692f0d74..c1bd33fe0 100644 --- a/templates/docs/meter/sma-home-manager_0.yaml +++ b/templates/docs/meter/sma-home-manager_0.yaml @@ -14,4 +14,4 @@ render: template: sma-home-manager usage: grid host: 192.0.2.2 # IP-Adresse oder Hostname - interface: eth0 # Netzwerkinterface # Optional + interface: eth0 # Netzwerkschnittstelle # Optional diff --git a/templates/evcc.io/brands.json b/templates/evcc.io/brands.json index 2d3405a55..902c1dd8a 100644 --- a/templates/evcc.io/brands.json +++ b/templates/evcc.io/brands.json @@ -16,6 +16,7 @@ "Elli", "Ensto", "Etrel", + "EVBox", "Fronius", "Garo", "go-eCharger", @@ -47,6 +48,7 @@ "Ubitricity", "Vestel", "Wallbe", + "wallbox", "Walther Werke", "Webasto", "Zaptec" diff --git a/util/templates/defaults.yaml b/util/templates/defaults.yaml index 2bbb5a3a5..9cb048938 100644 --- a/util/templates/defaults.yaml +++ b/util/templates/defaults.yaml @@ -63,10 +63,10 @@ params: type: number - name: interface description: - de: Netzwerkinterface + de: Netzwerkschnittstelle en: Network interface help: - de: Netzwerkinterface + de: Netzwerkschnittstelle en: Network interface advanced: true example: eth0 @@ -348,6 +348,30 @@ presets: en: Integrated device (no vehicle connection) - name: icon advanced: true + ocpp: + params: + - name: stationid + type: string + help: + en: The chargers unique station id (or chargepoint id) + de: Die Stations-ID der Wallbox (oder des Ladepunkts) + advanced: true + example: EVB-P12354 + - name: connector + help: + de: Ladepunkt, normalerweise 1 für den ersten Anschluss. + en: Connector number, usually 1 for first connector. + advanced: true + default: 1 + - name: idtag + type: string + help: + en: Token-ID returned to the charger for authorisation of charging sessions + de: Token-ID welche für die Freischaltung der Ladevorgänge an den Ladepunkt zurückgesendet wird + advanced: true + example: 04E6B78921BBA0 + - name: timeout + default: 10m modbus: interfaces: diff --git a/util/templates/includes/ocpp.tpl b/util/templates/includes/ocpp.tpl new file mode 100644 index 000000000..b78f0f4c0 --- /dev/null +++ b/util/templates/includes/ocpp.tpl @@ -0,0 +1,13 @@ +{{ define "ocpp" }} +type: ocpp +{{- if ne .stationid "" }} +stationid: {{ .stationid }} +{{- end }} +{{- if ne .connector "1" }} +connector: {{ .connector }} +{{- end }} +{{- if ne .idtag "" }} +idtag: {{ .idtag }} +{{- end }} +timeout: {{ .timeout }} +{{- end }}