Plugins
Plugins lesen und schreiben einzelne Werte an einem Gerät, z. B. eine Leistungsmessung, einen Zielstrom oder einen Freigabebefehl.
Sie stecken hinter den mitgelieferten Geräte-Templates und werden direkt referenziert, wenn du ein benutzerdefiniertes Gerät vom Typ type: custom aufbaust.
Plugins können für folgende Kategorien verwendet werden:
meter: PV-Anlage, Hausbatterie, Netz, Zählercharger: Wallboxen, schaltbare Steckdosen, Wärmepumpen, Heizstäbevehicle: Fahrzeugetariff: Tarife, Vorhersagencircuit: Lastmanagement
Auch Benachrichtigungen nutzen Plugins, um Lebenszyklus-Ereignisse zu versenden.
Plugin-Liste
Abschnitt betitelt „Plugin-Liste“- GPIO-Plugin: Plugin für den direkten Zugriff auf GPIO-Pins (nur Linux).
- Go-Plugin: Plugin, das Werte über ein Go-Skript bereitstellt oder entgegennimmt.
- HTTP-Plugin: Plugin, das über eine HTTP-API mit Endgeräten kommuniziert.
- JavaScript-Plugin: Plugin, das Werte über ein JavaScript-Skript bereitstellt oder entgegennimmt.
- Modbus-Plugin: Plugin zum Auslesen eines Modbus-fähigen Geräts.
- MQTT-Plugin: Plugin, um indirekt über MQTT mit MQTT-fähigen Geräten zu kommunizieren.
- Prometheus-Plugin: Plugin zum Lesen von Metriken aus Prometheus über PromQL.
- Shell-Plugin: Plugin, das ein Shell-Skript ausführt, um Daten zu extrahieren oder zu schreibende Daten entgegenzunehmen.
- SMA/Speedwire-Plugin: Plugin speziell für SMA-Geräte, die über das Speedwire-Protokoll kommunizieren.
- Websocket-Plugin: Plugin zum Empfangen von Gerätedaten über einen eigenen Webserver. Kann nur zum Lesen von Daten genutzt werden.
Liste der Hilfsplugins
Abschnitt betitelt „Liste der Hilfsplugins“- Calc-Plugin: Meta-Plugin, um Ausgaben anderer Plugins arithmetisch zu verknüpfen.
- Combined-Plugin: Meta-Plugin speziell für
charger, um die booleschen Statuswerte für den angeschlossenen (plugged) und ladenden (charging) Zustand zu einem einzigen Ladestatus zu kombinieren. - Const-Plugin: Spezielles Plugin, das einfach einen konstanten Wert zurückgibt.
- Error-Plugin: Spezielles Plugin, das einen bekannten Fehlerwert zurückgibt.
- Convert-Plugin: Meta-Plugin zur Datentyp-Konvertierung beim Schreiben (z. B. float zu int).
- Delta-Plugin: Meta-Plugin zur Umwandlung absoluter Werte in Änderungswerte (Deltas) beim Schreiben.
- Ignore-Plugin: Meta-Plugin zum Unterdrücken bestimmter Fehlermeldungen.
- IfElse-Plugin: Meta-Plugin für bedingte Schreibvorgänge mit zwei Zweigen (if/else).
- Map-Plugin: Meta-Plugin zur Übersetzung von Integer-Werten (z. B. gerätespezifische Modi in evcc-Modi).
- Meter-Plugin: Plugin, um einen anderen Zähler als Datenquelle zu verwenden.
- Sequence-Plugin: Meta-Plugin zur sequenziellen Ausführung mehrerer Schreibvorgänge.
- Sleep-Plugin: Hilfsplugin zum Verzögern von Aktionen (wird meist mit Sequence verwendet).
- Switch-Plugin: Meta-Plugin für bedingte Schreibvorgänge abhängig von Eingabewerten (wie switch/case).
- Valid-Plugin: Meta-Plugin, um Plugin-Werte anhand einer booleschen Validierung bereitzustellen.
- Watchdog-Plugin: Meta-Plugin zur automatischen Wiederholung von Schreibvorgängen in regelmäßigen Abständen.
Ein Plugin wird an ein Attribut eines Geräts gehängt.
Der Attributname (z. B. power, enable, soc) bestimmt die Rolle, source wählt den Plugin-Typ. Die übrigen Schlüssel sind Parameter des jeweiligen Plugins.
<attribut>: source: <plugin> <p-attr1>: ... <p-attr2>: ...Jedes Plugin wird entweder in einem lesenden oder einem schreibenden Kontext verwendet. Einige Parameter sind nur in einem der beiden Modi sinnvoll. Die vollständigen Attributlisten für Zähler, Wallboxen, Fahrzeuge und Tarife findest du auf der Seite Benutzerdefinierte Geräte.
Beim Lesen von Daten mithilfe eines Plugins können sogenannte Pipelines verwendet werden. Damit lassen sich gezielt einzelne Werte aus der Ausgabe des Plugins extrahieren. Dies ermöglicht es, komplexe Datenstrukturen wie JSON oder XML zu verarbeiten und die benötigten Informationen herauszufiltern. Mögliche Parameter für die Datenextraktion sind:
regex: Ein regulärer Ausdruck, um Werte aus dem empfangenen Text zu extrahieren.jq: Ein jq-Ausdruck, um Werte aus JSON-Strukturen zu extrahieren. Die vollständige Syntax und alle Möglichkeiten findest du in der jq-Dokumentation.quote: Boolescher Wert. Wenn er gesetzt ist, werden die Eingabedaten in Anführungszeichen gesetzt, bevor sie an jq weitergegeben werden. Dadurch kann jq Strings ohne Anführungszeichen (z. B. von MQTT) verarbeiten. Bei einem MQTT-Wert wieChargingkannst duquote: trueundjq: '. == "Charging"'verwenden.unpack: Konvertiert Werte aus anderen Zahlenrepräsentationen, z. B.hex.decode: Dekodiert Binärformate wieuint32,float32usw.
Bekannte Fehlerwerte
Abschnitt betitelt „Bekannte Fehlerwerte“HTTP-, MQTT- und Websocket-Plugins können spezielle Fehlerwerte als String zurückgeben. evcc erkennt diese und wandelt sie in interne Fehlercodes um, anstatt sie als Daten zu behandeln. Das ist z. B. nützlich für benutzerdefinierte Fahrzeugintegrationen, bei denen die Datenquelle den Zustand des Fahrzeugs kennt.
ErrAsleep: Fahrzeug schläft. evcc kann das Fahrzeug dann wecken und es erneut versuchen.ErrMustRetry: Vorgang soll erneut versucht werden (z. B. bei Rate-Limiting).ErrNotAvailable: Wert ist nicht verfügbar. evcc behandelt dies als permanenten Fehler bis zum nächsten Neustart.
Wenn ein Plugin den String ErrAsleep als Antwort liefert, erzeugt evcc intern den entsprechenden Fehler.
Das Error-Plugin nutzt denselben Mechanismus, um einen festen Fehlerwert als Konstante zurückzugeben.
Schreiben
Abschnitt betitelt „Schreiben“Beim Schreiben können Parameter in der Konfiguration Platzhalter enthalten.
Die Daten werden in Form von ${var[:format]} zur Verfügung gestellt.
Wenn kein Format angegeben ist, werden die Daten im Go-Standardformat %v bereitgestellt.
Die Variablen werden durch den entsprechenden Wert ersetzt, bevor das Plugin ausgeführt wird.
Zusätzlich können sämtliche Funktionen der Go-Template-Bibliothek verwendet werden, um komplexere Datentransformationen durchzuführen.
Plugins
Abschnitt betitelt „Plugins“GPIO lesen schreiben
Abschnitt betitelt „GPIO “Das gpio-Plugin ermöglicht den direkten Zugriff auf GPIO-Pins (General Purpose Input/Output) unter Linux.
Es eignet sich besonders für den Raspberry Pi und ähnliche Einplatinencomputer.
Parameter:
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| function | string | ja | Modus: read (Eingang) oder write (Ausgang) |
| pin | int | ja | Pin-Nummer (BCM-Nummerierung, z. B. GPIO 17) |
Funktionsweise:
- Lesen (
function: read): Liest den Zustand eines GPIO-Pins als booleschen Wert (true= HIGH,false= LOW) - Schreiben (
function: write): Setzt einen GPIO-Pin auf HIGH (true) oder LOW (false)
Eingänge nutzen immer den internen Pull-up-Widerstand, daher wird ein Schaltkontakt zwischen Pin und Masse (GND) angeschlossen.
Ein offener Kontakt ergibt true (HIGH), ein geschlossener false (LOW).
Für ein Begrenzungssignal nutze den Öffnerkontakt (NC) des Relais.
Im Normalbetrieb ist der Kontakt geschlossen und der Pin liefert false.
Wird die Begrenzung aktiviert, öffnet der Kontakt und der Pin liefert true.
Auch ein Kabelbruch ergibt true, sodass die Begrenzung ausfallsicher greift.
Die Pin-Nummerierung folgt dem BCM-Schema (Broadcom-Nummern, nicht die physische Pin-Position). Eine Pinbelegung des Raspberry Pi findest du z. B. auf pinout.xyz.
Beispiel Lesen:
source: gpiofunction: readpin: 17 # BCM-Pin-NummerBeispiel Schreiben:
source: gpiofunction: writepin: 27 # BCM-Pin-NummerGo lesen schreiben
Abschnitt betitelt „Go “Das go-Plugin verwendet den Interpreter Yaegi, um Go-Code zur Laufzeit auszuführen.
Es ist besonders nützlich für typsichere Berechnungen und komplexe Datenverarbeitungslogik.
Verfügbare Pakete der Go-Standardbibliothek
Abschnitt betitelt „Verfügbare Pakete der Go-Standardbibliothek“Folgende Go-Pakete stehen automatisch zur Verfügung und müssen nicht importiert werden:
fmt: Formatierte Ein-/Ausgabemath: Mathematische Funktionenstrings: String-Manipulationtime: Zeit- und Datumsfunktionen
Beispiel Lesen:
source: goscript: | res := 500.0 res * 2 // liefert 1000.0Beispiel mit Zeitfunktionen:
source: goscript: | hour := time.Now().Hour() price := 50.0 // Nachttarif if hour >= 9 && hour < 17 { price = 100.0 // Tarifpreis während der Geschäftszeiten } price // liefert 50.0 oder 100.0 je nach TageszeitBeispiel mit String-Verarbeitung:
source: goscript: | text := "hello world" strings.ToUpper(text) // liefert "HELLO WORLD"Wenn das go-Plugin zum Schreiben verwendet wird, wird der zu schreibende Wert dem Skript als Variable übergeben:
Beispiel Schreiben:
maxcurrent: source: go script: | fmt.Printf("Setze Ladestrom: %d A\n", maxcurrent) // Variable maxcurrent ist automatisch verfügbarInput- und Output-Transformationen
Abschnitt betitelt „Input- und Output-Transformationen“Die Plugins go und js unterstützen die Parameter in und out, um Werte aus anderen Quellen als Variablen im Skript zu verwenden oder das Skriptergebnis an andere Plugins weiterzuleiten.
Input-Transformationen (in)
Abschnitt betitelt „Input-Transformationen (in)“Mit dem Parameter in kannst du Werte aus anderen Quellen als Variablen in deinem Skript verwenden.
Jeder Eintrag benötigt name (Variablenname im Skript), type (bool, int, float, string) und config (Plugin-Konfiguration).
Dieses Beispiel zeigt eine bedingte Logik, die mit den einfachen Calc-Operationen nicht möglich ist:
power: source: go script: | // Leistung abhängig von Ladestand und Standby power := 5000.0 // normal if standby { power = 0.0 // im Standby keine Last } else if soc < 20.0 { power = 1000.0 // niedrig } power // liefert 5000.0 (standby=false, soc>=20) in: - name: soc type: float config: source: const value: 85.0 - name: standby type: bool config: source: const value: falseOutput-Transformationen (out)
Abschnitt betitelt „Output-Transformationen (out)“Der Parameter out leitet das Skriptergebnis an andere Plugins weiter.
Das ist besonders im Schreibkontext nützlich, z. B. wenn das Skriptergebnis per MQTT oder HTTP weiterverarbeitet werden soll.
Jeder Eintrag benötigt name, type und config, analog zu in.
maxcurrent: source: go script: | watts := maxcurrent * 230 watts out: - name: watts type: float config: source: mqtt topic: heater/target_powerHTTP lesen schreiben
Abschnitt betitelt „HTTP “Das http-Plugin führt HTTP-Aufrufe aus, um Daten zu lesen oder zu aktualisieren.
Außerdem kann es JSON-Datenstrukturen (z. B. von REST-APIs) per jq-Abfrage auslesen und einfach umformen.
Der volle Funktionsumfang ist in der offiziellen jq-Dokumentation beschrieben.
Als Authentifizierungsmethoden stehen basic, bearer und digest zur Verfügung.
Die Namen der jeweiligen Parameter finden sich hier.
Authentifizierung
Abschnitt betitelt „Authentifizierung“Für HTTP-Anfragen stehen verschiedene Authentifizierungsmethoden zur Verfügung:
Basic-Authentifizierung:
auth: type: basic user: <benutzername> password: <passwort>Bearer-Token (z. B. für JWT):
auth: type: bearer token: <token>Digest-Authentifizierung:
auth: type: digest user: <benutzername> password: <passwort>Benutzerdefinierte Authentifizierung:
Für komplexere Authentifizierungsszenarien können benutzerdefinierte Authentifizierungs-Plugins entwickelt werden.
Diese werden über den Parameter source eingebunden:
auth: source: <plugin-name> user: <benutzername> password: <passwort> # weitere plugin-spezifische ParameterDies ermöglicht die Integration von Geräten mit speziellen Authentifizierungsanforderungen, ohne den gesamten HTTP-Plugin-Code anpassen zu müssen.
Beispiel Lesen:
source: httpuri: https://volkszaehler/api/data/<uuid>.json?from=nowmethod: GET # Standard-HTTP-Methodeheaders: - content-type: application/jsonauth: # Basic-Authentifizierung type: basic user: foo password: barinsecure: false # auf true setzen, um selbstsignierten Zertifikaten zu vertrauenjq: .data.tuples[0][1] # JSON-Antwort auswertenscale: 0.001 # Faktor für das Ergebnis, z. B. zur Umrechnung von W in kWcache: 60s # Cache-Dauer der Antworttimeout: 10s # Timeout im Go-Duration-Format, siehe https://golang.org/pkg/time/#ParseDurationsource: httpuri: http://charger/statusjq: .total_power > 10 # wandelt eine JSON-Ganzzahl in einen booleschen Wert umBeispiel Schreiben:
body: %v # nur bei PUT- oder POST-Anfragenenable: source: http uri: "http://charger/relay/0?turn={{if .enable}}on{{else}}off{{end}}"Dynamische URIs:
uri und body sind Go-Templates, die bei jeder Anfrage neu ausgewertet werden. Neben den sprig-Funktionen stehen addDate und timeRound zur Verfügung. Damit lässt sich z. B. eine Vorhersage-API immer für einen gleitenden Zeitraum abfragen:
forecast: source: http uri: https://api.example.org/forecast?from={{ now | date "2006-01-02" }}&to={{ addDate now 0 0 2 | date "2006-01-02" }}JavaScript lesen schreiben
Abschnitt betitelt „JavaScript “evcc integriert einen JavaScript-Interpreter mit der Bibliothek Underscore.js, die direkt über _. erreichbar ist, z. B. _.random(0,5).
Das js-Plugin kann JavaScript-Code über den Parameter script ausführen. Das ist besonders für schnelles Prototyping hilfreich:
Beispiel Lesen:
source: jsscript: | var res = 500; 2 * res; // liefert 1000Wenn das js-Plugin zum Schreiben verwendet wird, wird der zu schreibende Wert dem Skript als Variable übergeben:
Beispiel Schreiben:
maxcurrent: source: js script: | console.log(maxcurrent);Das js-Plugin unterstützt dieselben Input- und Output-Transformationen (in/out) wie das go-Plugin.
Modbus lesen schreiben
Abschnitt betitelt „Modbus “Das modbus-Plugin kann Daten von jedem Modbus-fähigen Gerät oder SunSpec-kompatiblen Wechselrichter lesen.
Viele Zähler sind bereits vorkonfiguriert (siehe MBMD Supported Devices).
Außerdem lassen sich Modbus-Register schreiben, um weitere Wallboxen einzubinden.
Beispiel:
source: modbusid: 1uri: 192.168.1.10:502register: address: 300 type: holding decode: uint16Weitere Details findest du in der Modbus-Dokumentation.
MQTT lesen schreiben
Abschnitt betitelt „MQTT “Das mqtt-Plugin ermöglicht das Lesen von Werten über MQTT-Topics.
Das ist besonders für Zähler nützlich, z. B. wenn diese ihre Daten bereits über MQTT bereitstellen.
Ein Beispiel, wie Modbus-Messdaten nach MQTT gelangen, findest du in der MBMD-Dokumentation.
Parameter (Lesen):
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| topic | string | ja | MQTT-Topic zum Lesen |
| timeout | duration | nein | Maximales Alter empfangener Werte |
| scale | float | nein | Skalierungsfaktor für das Ergebnis (z. B. 0,001 zur Umrechnung von Wh in kWh) |
Das Plugin gibt einen Fehler zurück, wenn innerhalb der mit timeout festgelegten Zeit kein neuer Wert empfangen wurde.
Wenn timeout nicht gesetzt ist, werden Werte beliebigen Alters akzeptiert, sobald die erste Nachricht empfangen wurde.
Es wird empfohlen, einen Timeout zu setzen, um zu erkennen, wenn die Quelle keine aktuellen Daten mehr liefert.
Für die Datenextraktion stehen die unter Lesen beschriebenen Pipeline-Parameter zur Verfügung (regex, jq, quote usw.).
Beispiel Lesen:
source: mqtttopic: mbmd/sdm1-1/Powertimeout: 30s # Werte älter als timeout nicht akzeptierenscale: 0.001 # Faktor für das Ergebnis, z. B. zur Umrechnung von Wh in kWhParameter (Schreiben):
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| topic | string | ja | MQTT-Topic zum Schreiben |
| payload | string | nein | Payload-Template (verwendet Wert im Standardformat, wenn nicht gesetzt) |
Für den Schreibzugriff werden die Daten mit dem Attribut payload bereitgestellt.
Falls dieser Parameter in der Konfiguration fehlt, wird der Wert im Standardformat geschrieben.
Beispiel Schreiben:
source: mqtttopic: mbmd/charger/maxcurrentpayload: ${var:%d}Prometheus lesen
Abschnitt betitelt „Prometheus “Das prometheus-Plugin liest Metriken aus einer Prometheus-Instanz über PromQL-Abfragen.
Dies ist nützlich, wenn bereits Monitoring-Daten in Prometheus vorliegen, die in evcc verwendet werden sollen.
Parameter:
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| uri | string | ja | URL des Prometheus-Servers |
| query | string | ja | PromQL-Abfrage |
| timeout | duration | nein | Timeout (Standard: 2 Minuten) |
Unterstützte Abfrageergebnisse:
- Scalar: Ein einzelner Zahlenwert
- Vector: Ein Vektor mit genau einem Metrik-Eintrag
Beispiel:
power: source: prometheus uri: http://prometheus.local:9090 query: "sum(household_power_watts)" timeout: 30sBeispiel mit Zeitbereich:
energy: source: prometheus uri: http://prometheus.local:9090 query: "increase(energy_total_kwh[1h])"Die Abfrage muss einen einzelnen numerischen Wert zurückgeben. Bei Vektor-Ergebnissen muss genau eine Metrik enthalten sein.
Shell-Skript lesen schreiben
Abschnitt betitelt „Shell-Skript “Das script-Plugin führt externe Skripte aus, um Daten zu lesen oder zu aktualisieren. Damit lassen sich beliebige externe Funktionen einbinden.
Beispiel Lesen:
source: scriptcmd: /bin/bash -c "cat /dev/urandom"timeout: 5sBeispiel Schreiben:
source: scriptcmd: /home/user/my-script.sh ${enable:%b} # booleschen Wert enable als 0/1 formatierentimeout: 5sSMA/Speedwire lesen
Abschnitt betitelt „SMA/Speedwire “Das sma-Plugin bietet eine Schnittstelle zu SMA-Geräten, die das Speedwire-Protokoll unterstützen.
Beispiel Lesen:
source: smauri: 192.168.4.51 # Alternative zu serialserial: 123456 # Alternative zu urivalue: ActivePowerPlus # ID des zu lesenden Wertspassword: "0000" # optional (Standard: 0000)interface: eth0 # optionalscale: 1 # optionaler Skalierungsfaktor für den WertUnterstützte Werte für value findest du in der Diagnoseausgabe des Befehls evcc meter (bei konfigurierten SMA-Geräten vom Typ meter).
Alle möglichen Werte sind hier als Konstanten aufgeführt (verwende den Namen der Konstante für value).
Websocket lesen
Abschnitt betitelt „Websocket “Das websocket-Plugin bietet einen WebSocket-Listener.
Außerdem kann es JSON-Datenstrukturen über jq-ähnliche Abfragen auslesen.
Damit lassen sich z. B. Daten vom Volkszähler-Push-Server empfangen.
Für die Datenextraktion stehen die unter Lesen beschriebenen Pipeline-Parameter zur Verfügung (regex, jq, quote usw.).
Beispiel Lesen:
source: httpuri: ws://<volkszaehler host:port>/socketjq: .data | select(.uuid=="<uuid>") .tuples[0][1] # JSON-Nachricht auswertenscale: 0.001 # Faktor für das Ergebnis, z. B. zur Umrechnung von Wh in kWhtimeout: 30s # Fehler, wenn 30 Sekunden lang kein Update empfangen wirdHilfsplugins
Abschnitt betitelt „Hilfsplugins“Calc lesen
Abschnitt betitelt „Calc “Das calc-Plugin erlaubt es, mehrere Einzelwerte mathematisch weiterzuverarbeiten:
Beispiel Lesen:
source: calcadd:- source: ... ...- source: ... ...source: calcmul:- source: calc sign: source: ... (power) ...- source: ... (current) ...Unterstützt werden die Operationen Addition (add), Multiplikation (mul), Division (div), Vorzeichenumkehr (sign), Absolutwert (abs), Minimum (min) und Maximum (max).
Mit scale: -1 bei einem der Werte kann eine einfache Subtraktion durchgeführt werden, mit scale: 0.001 eine Division, z. B. zur Umrechnung von Wh in kWh.
Mit sign: wird jede positive Zahl zu +1, jede negative zu -1, und 0 bleibt 0. In Verbindung mit mul lassen sich so Vorzeichen auf andere Werte übertragen.
So lässt sich z. B. bei Zählern die Richtung der Leistung (Einspeisung oder Netzbezug) auf die gemessenen Ströme übertragen.
Mit abs: wird der Absolutwert einer Zahl berechnet.
Mit min: und max: wird der Minimalwert bzw. der Maximalwert berechnet.
Das calc-Plugin ist hilfreich, um z. B.
- Leistungswerte einzelner PV-Strings zu summieren (addieren)
- die Scheinleistung aus Spannung und Strom zu berechnen (multiplizieren)
- getrennte Leistungswerte für Netzbezug und Einspeisung zu einem vorzeichenbehafteten Einzelwert zu kombinieren (subtrahieren)
- prozentuale Füllstände zu berechnen (dividieren)
- die richtige Richtung des Stromflusses zu bestimmen (sign)
- bekannte Offsets zu eliminieren (addieren mit dem
const-Plugin)
Combined lesen
Abschnitt betitelt „Combined “Das combined-Plugin fasst die booleschen Statuswerte Plugged (angeschlossen) und Charging (lädt) zu einem evcc-kompatiblen Ladestatus A bis F zusammen.
Es wird z. B. zusammen mit einer OpenWB-MQTT-Integration verwendet.
Beispiel Lesen:
source: combinedplugged: source: mqtt topic: openWB/lp/1/boolPlugStatcharging: source: mqtt topic: openWB/lp/1/boolChargeStatConst lesen
Abschnitt betitelt „Const “Das const-Plugin gibt einen konstanten Wert zurück.
Es eignet sich z. B. dazu, in Verbindung mit dem calc-Plugin feste Korrekturwerte (Offset) auf einen variablen Wert anzuwenden oder Mess- und Statuswerte zu Testzwecken zu simulieren.
Beispiel Lesen:
source: constvalue: -16247Error lesen
Abschnitt betitelt „Error “Das error-Plugin gibt immer einen bekannten Fehlerwert zurück.
Es ist nützlich, um ein nicht implementiertes Attribut explizit als nicht verfügbar zu kennzeichnen.
Parameter:
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| error | string | ja | Fehlerwert (ErrAsleep, ErrMustRetry oder ErrNotAvailable) |
Beispiel:
soc: source: error error: ErrNotAvailableConvert schreiben
Abschnitt betitelt „Convert “Das convert-Plugin konvertiert Datentypen beim Schreiben.
Es wird verwendet, wenn ein Plugin einen anderen Datentyp erwartet, als evcc liefert.
Parameter:
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| convert | string | ja | Konvertierungstyp |
| set | config | ja | Plugin zum Schreiben nach Konvertierung |
Unterstützte Konvertierungen:
| Konvertierung | Beschreibung |
|---|---|
| float2int | Float64 → Int64 (Nachkommastellen werden abgeschnitten) |
| int2float | Int64 → Float64 |
| int2bytes | Int64 → Byte-Array (Big Endian, 8 Bytes) |
| bool2int | Bool → Int64 (true=1, false=0) |
Beispiel (evcc liefert float, Gerät erwartet int):
limitsoc: source: convert convert: float2int set: source: modbus uri: 192.168.1.10:502 id: 1 register: address: 41009 type: writesingle encoding: uint16In diesem Beispiel konvertiert evcc einen Float-Wert wie 85.5 in 85, bevor er in das Modbus-Register geschrieben wird.
Delta schreiben
Abschnitt betitelt „Delta “Das delta-Plugin wandelt absolute Werte in Änderungswerte (Deltas) um.
Es wird für Geräte verwendet, die geschriebene Werte zu einem internen Summenwert addieren, anstatt sie direkt zu setzen.
Parameter:
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| get | config | nein | Plugin zum Lesen des aktuellen Gesamtwerts vom Gerät |
| set | config | ja | Plugin zum Schreiben des berechneten Deltas |
Funktionsweise:
- Der Eingabewert wird empfangen (z. B.
1000) - Falls
getkonfiguriert ist, wird der aktuelle Gesamtwert vom Gerät gelesen - Das Delta wird berechnet:
delta = new_value - current_total - Das Delta wird über das
set-Plugin geschrieben - Der interne Zustand wird aktualisiert
Ohne den Parameter get führt das Plugin den Gesamtwert intern (beginnend bei 0).
Bei einem Neustart von evcc geht die Synchronisation mit dem Gerät verloren.
Daher wird empfohlen, get zu konfigurieren, wenn das Gerät ein lesbares Summenregister bereitstellt.
Unterstützte Datentypen: int64, float64
Anwendungsfall:
Einige Wärmepumpen (z. B. Ochsner) haben Register, die Änderungswerte statt absolute Werte erwarten.
Beim Schreiben von 500 addiert das Gerät 500 W zum internen Wert, anstatt ihn auf 500 W zu setzen.
Um von 1000 W auf 1500 W zu erhöhen, muss +500 geschrieben werden.
Um zu reduzieren, werden negative Werte geschrieben (z. B. -300).
Beispiel Schreiben:
setmaxpower: source: delta get: # Aktuellen Gesamtwert vom Gerät lesen source: modbus uri: 192.168.1.50:502 id: 50 register: address: 2012 # Internes Summenregister des Geräts type: input decode: uint16 set: # Berechnetes Delta schreiben source: modbus uri: 192.168.1.50:502 id: 50 register: address: 2201 # Delta-Register type: writeholding decode: uint16Beispiel mit Watchdog:
Das Delta-Plugin wird häufig mit dem Watchdog-Plugin kombiniert, wenn das Gerät regelmäßige Updates benötigt:
setmaxpower: source: watchdog timeout: 60s # Erneutes Senden alle 30 Sekunden set: source: delta # Absolute Werte in Deltas umwandeln get: # Aktuellen Gesamtwert lesen source: modbus uri: 192.168.1.50:502 id: 50 register: address: 2012 # Summenwert-Register type: input decode: uint16 set: # Delta schreiben source: modbus uri: 192.168.1.50:502 id: 50 register: address: 2201 # Delta-Register type: writeholding decode: uint16Ignore schreiben
Abschnitt betitelt „Ignore “Das ignore-Plugin unterdrückt bestimmte Fehlermeldungen beim Schreiben.
Es wird verwendet, wenn ein Gerät harmlose Fehler zurückgibt, die ignoriert werden können.
Parameter:
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| error | string | ja | Präfix der Fehlermeldung, das ignoriert werden soll |
| set | config | ja | Plugin zum Schreiben |
Funktionsweise:
- Das verschachtelte
set-Plugin wird ausgeführt - Falls ein Fehler auftritt, wird geprüft, ob die Fehlermeldung mit dem
error-String beginnt - Wenn ja, wird der Fehler ignoriert und der Schreibvorgang gilt als erfolgreich
- Wenn nein, wird der Fehler normal weitergegeben
Unterstützte Datentypen: int64, float64, bool, []byte
Beispiel:
batterymode: source: switch switch: - case: 1 # normal set: source: const value: 2 set: source: ignore error: "modbus: response data size '18' does not match count '4'" set: source: modbus uri: 192.168.1.10:502 id: 1 register: address: 0x1110 type: writemultiple encoding: int16In diesem Beispiel gibt das Gerät einen harmlosen Modbus-Fehler zurück, der ignoriert wird.
IfElse schreiben
Abschnitt betitelt „IfElse “Das ifelse-Plugin führt bedingte Schreibvorgänge mit zwei Zweigen aus.
Je nach Eingabewert wird entweder das if- oder das else-Plugin ausgeführt.
Parameter:
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| if | config | ja | Plugin, das bei erfüllter Bedingung ausgeführt wird |
| else | config | ja | Plugin, das bei nicht erfüllter Bedingung ausgeführt wird |
Funktionsweise:
- Bei
bool-Werten:trueführtifaus,falseführtelseaus - Bei
int64-Werten:> 0führtifaus, sonstelse
Unterstützte Datentypen: int64, bool
Beispiel (unterschiedliche Endpunkte für Ein- und Ausschalten):
enable: source: ifelse if: source: http uri: http://device.local/api/on method: POST else: source: http uri: http://device.local/api/off method: POSTMap lesen schreiben
Abschnitt betitelt „Map “Das map-Plugin übersetzt Integer-Werte in andere Integer-Werte mithilfe einer Lookup-Tabelle.
Es wird häufig verwendet, um gerätespezifische Werte in evcc-Standardwerte zu konvertieren und umgekehrt.
Parameter:
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| values | map[int64]int64 | ja | Lookup-Tabelle, die Eingabewerte Ausgabewerten zuordnet |
| get | config | nein | Plugin zum Lesen (nur beim Lesen erforderlich) |
| set | config | nein | Plugin zum Schreiben (nur beim Schreiben erforderlich) |
Funktionsweise:
Beim Lesen:
- Das
get-Plugin liefert einen Wert (z. B.0) - Der Wert wird in der
values-Tabelle nachgeschlagen - Der zugeordnete Wert wird zurückgegeben (z. B.
0→2)
Beim Schreiben:
- Der Eingabewert wird empfangen (z. B.
3) - Der Wert wird in der
values-Tabelle nachgeschlagen - Der zugeordnete Wert wird an das
set-Plugin übergeben (z. B.3→6)
Findet sich kein passender Wert in der Tabelle, meldet das Plugin einen Fehler.
Unterstützte Datentypen: int64 (nur Integer-Werte)
Beispiel Lesen (Gerätewert → evcc):
getmode: source: map values: 0: 2 # Gerät "Free" → evcc "normal" 1: 1 # Gerät "Forced off" → evcc "reduced" 2: 3 # Gerät "Recommended on" → evcc "boost" 3: 3 # Gerät "Forced on" → evcc "boost" get: source: modbus uri: 192.168.1.10:502 id: 1 register: address: 55 type: holding encoding: int16Beispiel Schreiben (evcc → Gerätewert):
setmode: source: map values: 1: 1 # evcc "reduced" → Gerät "Forced off" 2: 0 # evcc "normal" → Gerät "Free" 3: 3 # evcc "boost" → Gerät "Forced on" set: source: modbus uri: 192.168.1.10:502 id: 1 register: address: 55 type: writeholding encoding: int16Meter lesen
Abschnitt betitelt „Meter “Das meter-Plugin ermöglicht es, einen anderen Zähler als Datenquelle zu verwenden.
Das ist nützlich, wenn du ein bestehendes Gerät für mehrere Messwerte verwenden möchtest oder für unterschiedliche Attribute verschiedene Methoden eines Geräts brauchst.
Der Abschnitt config enthält die vollständige Template-Konfiguration des einzubettenden Zählers.
Der Parameter method bestimmt, welcher Wert gelesen wird: power, energy, returnenergy oder soc.
Beispiel Lesen:
meters: - name: battery type: custom power: source: meter config: type: template template: shelly-1pm host: 192.168.178.21 channel: 0 method: power scale: -1 energy: source: meter config: type: template template: shelly-1pm host: 192.168.178.21 channel: 0 method: energy soc: source: mqtt topic: Haus/Batterie jq: .soc timeout: 60sIn diesem Beispiel dient ein Shelly 1PM als Datenquelle für Leistung und Energie einer Hausbatterie, während der Ladestand über MQTT abgerufen wird.
Sequence schreiben
Abschnitt betitelt „Sequence “Das sequence-Plugin führt mehrere Schreibvorgänge nacheinander aus.
Alle verschachtelten Plugins erhalten denselben Eingabewert und werden in der definierten Reihenfolge ausgeführt.
Bei einem Fehler stoppt die Ausführung sofort.
Parameter:
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| set | [config] | ja | Array von verschachtelten Plugin-Konfigurationen |
Funktionsweise:
- Der Eingabewert wird empfangen
- Jedes Plugin in der
set-Liste wird nacheinander mit diesem Wert aufgerufen - Bei einem Fehler wird die Sequenz abgebrochen und der Fehler zurückgegeben
- Die Sequenz gilt nur dann als erfolgreich, wenn alle Plugins fehlerfrei durchgelaufen sind
Unterstützte Datentypen: int64, float64, bool
Anwendungsfälle:
- Mehrere HTTP-Aufrufe nacheinander ausführen
- Mit dem
sleep-Plugin für zeitlich verzögerte Aktionen kombinieren - Mehrere Modbus-Register in einem Schritt schreiben
- Werte an mehrere Ziele weitergeben
Beispiel 1: Mehrere HTTP-Aufrufe
setmode: source: sequence set: - source: http uri: http://device.local/api/pin1 method: POST body: '{"value": "on"}' - source: http uri: http://device.local/api/pin4 method: POST body: '{"value": "off"}'Beispiel 2: Kombination mit switch
batterymode: source: sequence set: - source: switch switch: - case: 1 # normal set: source: http uri: http://battery.local/api/mode body: "automatic" - case: 3 # charge set: source: sequence set: - source: sleep duration: 1s - source: http uri: http://battery.local/api/charge body: "5000" # 5 kW - source: mqtt topic: home/battery/status payload: "mode_${batterymode}"Ablauf bei batterymode: 1 (normal):
- Äußere
sequenceempfängt Wert1 - Erster Schritt:
switchprüft den Wert1- Fall
1trifft zu → HTTP-Aufruf an/api/modemit Bodyautomatic
- Fall
- Zweiter Schritt:
mqttsendet eine Nachricht anhome/battery/statusmit Payloadmode_1 - Fertig
Ablauf bei batterymode: 3 (charge):
- Äußere
sequenceempfängt Wert3 - Erster Schritt:
switchprüft den Wert3- Fall
3trifft zu → Inneresequencewird ausgeführt:- 1 Sekunde warten (
sleep) - HTTP-Aufruf an
/api/chargemit Body5000
- 1 Sekunde warten (
- Fall
- Zweiter Schritt:
mqttsendet eine Nachricht anhome/battery/statusmit Payloadmode_3 - Fertig
Der Wert fließt durch alle Plugins, wobei switch abhängig vom Wert unterschiedliche Aktionen ausführt und mqtt am Ende immer eine Nachricht sendet.
Sleep schreiben
Abschnitt betitelt „Sleep “Das sleep-Plugin fügt eine Verzögerung ein.
Es wird typischerweise innerhalb eines sequence-Plugins verwendet, um zeitliche Abstände zwischen Aktionen zu schaffen.
Parameter:
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| duration | duration | ja | Wartezeit (z. B. 1s, 500ms, 0s für keine Verzögerung) |
Beispiel:
setmode: source: sequence set: - source: http uri: http://device.local/api/prepare method: POST - source: sleep duration: 500ms - source: http uri: http://device.local/api/activate method: POSTSwitch schreiben
Abschnitt betitelt „Switch “Das switch-Plugin führt bedingte Schreibvorgänge durch, ähnlich einer switch/case-Anweisung in Programmiersprachen.
Je nach Eingabewert wird die entsprechende Aktion ausgeführt.
Parameter:
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| switch | [case] | ja | Liste von Fällen mit case- und set-Konfiguration |
| default | config | nein | Fallback-Plugin, wenn kein Fall zutrifft |
Funktionsweise:
- Der Eingabewert wird mit den
case-Werten verglichen - Bei Übereinstimmung wird das entsprechende
set-Plugin ausgeführt - Falls kein Fall zutrifft und
defaultdefiniert ist, wird dieses ausgeführt - Falls kein Fall zutrifft und kein
defaultdefiniert ist, meldet das Plugin einen Fehler
Unterstützte Datentypen: int64 (nur Integer-Werte)
Beispiel:
setmode: source: switch switch: - case: 1 # reduced set: source: http uri: http://device.local/api/mode body: "eco" - case: 2 # normal set: source: http uri: http://device.local/api/mode body: "normal" - case: 3 # boost set: source: http uri: http://device.local/api/mode body: "boost"Valid lesen
Abschnitt betitelt „Valid “Das valid-Plugin ermöglicht es, Plugin-Werte anhand einer booleschen Validierung bereitzustellen.
Es trennt die Gültigkeit eines Werts von seinem eigentlichen Inhalt.
Wenn die Validierung false zurückgibt, wird der Wert als nicht verfügbar betrachtet.
Dies ist besonders nützlich für Integrationen wie ioBroker, die Gültigkeit und Wert getrennt bereitstellen.
Beispiel Lesen:
source: validvalid: source: mqtt topic: iobroker/wallbox/power/validvalue: source: mqtt topic: iobroker/wallbox/power/valueIn diesem Beispiel wird der Wert nur verwendet, wenn das valid-Topic true zurückgibt.
Wenn es false zurückgibt, wird der Wert als nicht verfügbar markiert.
Watchdog schreiben
Abschnitt betitelt „Watchdog “Das watchdog-Plugin ist ein Wrapper-Plugin, das Schreibvorgänge automatisch in regelmäßigen Abständen wiederholt.
Manche Geräte (z. B. Hausbatterien, Wechselrichter) erwarten, dass Steuerbefehle regelmäßig wiederholt werden, um aktiv zu bleiben.
Das Watchdog-Plugin überwacht Schreibvorgänge und wiederholt sie automatisch jeweils nach Ablauf des halben Timeouts.
Parameter:
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| timeout | duration | ja | Zeitintervall für Wiederholungen (Wert wird alle timeout/2 erneut geschrieben) |
| reset | string | [string] | nein | Wert(e), bei denen Wiederholungen gestoppt werden |
| initial | string | nein | Wert, der beim Start einmalig geschrieben wird |
| defer | bool | nein | Verzögert Updates, statt sie sofort auszuführen (Standard: false) |
| set | config | ja | Verschachteltes Plugin für den eigentlichen Schreibvorgang |
Funktionsweise:
- Start: Falls
initialkonfiguriert ist, wird dieser Wert beim Start einmalig geschrieben - Schreiben: Wenn ein Wert geschrieben wird, prüft das Plugin, ob dieser in der
reset-Liste steht - Watchdog aktiv: Falls der Wert nicht in
resetsteht, startet der Watchdog und schreibt den Wert automatisch im halbentimeout-Intervall erneut - Watchdog stoppt: Falls der Wert in
resetsteht, werden keine Wiederholungen durchgeführt
reset-Parameter:
- Definiert Werte, bei denen der Watchdog gestoppt wird
- Kann ein einzelner Wert (
reset: 0) oder mehrere Werte (reset: [0, 1]) sein - Typischerweise für sichere Zustände oder Standardzustände verwendet, die keine kontinuierliche Wiederholung benötigen
initial-Parameter:
- Optionaler Wert, der beim Start des Plugins einmalig geschrieben wird
- Nützlich, um einen definierten Startzustand zu setzen
- Wird vor allen anderen Schreibvorgängen ausgeführt
defer-Parameter:
- Stellt sicher, dass zwischen zwei Updates ein Mindestabstand eingehalten wird
- Der Watchdog wird während der Verzögerung gestoppt und nach Ablauf mit dem neuen Wert neu gestartet
- Sinnvoll, wenn Geräte eine Mindestwartezeit zwischen Modusänderungen benötigen
- Die Verzögerung wird anhand der Zeit seit dem letzten Update berechnet
- Reset-Werte werden immer sofort (ohne Verzögerung) geschrieben
Unterstützte Datentypen: int64, float64, bool
Beispiel Schreiben:
source: watchdogtimeout: 60sreset: 0set: source: modbus uri: 192.168.1.10:502 id: 1 register: address: 100 type: writemultiple encoding: uint16In diesem Beispiel werden Werte automatisch alle 30 s wiederholt, außer wenn der Wert 0 geschrieben wird.
Ablaufbeispiel mit timeout: 60s, reset: 0:
- Plugin startet
- Wert
100schreiben → Watchdog läuft, Wert wird alle 30 s wiederholt - Nach 2 Minuten: Wert
100wurde 5-mal geschrieben (bei 0, 30, 60, 90 und 120 s) - Wert
200schreiben → Watchdog läuft weiter, jetzt mit dem neuen Wert200alle 30 s - Wert
0schreiben → Watchdog stoppt (da0inresetdefiniert ist) - Keine weiteren Wiederholungen, bis ein neuer Wert ungleich
0geschrieben wird
Beispiel mit Batteriesteuerung (batterymode verwendet Werte 1=normal, 2=hold, 3=charge, 4=holdcharge, 5=discharge):
batterymode: source: watchdog timeout: 60s reset: 1 # Wiederholungen im Normalbetrieb stoppen set: source: switch switch: - case: 1 # normal set: source: modbus # ... Modbus-Konfiguration für Normalbetrieb - case: 2 # hold set: source: modbus # ... Modbus-Konfiguration für Haltemodus - case: 3 # charge set: source: modbus # ... Modbus-Konfiguration für Lademodus