Plugins
Plugins can be used to integrate devices and external data sources into evcc for which there is no direct support. Plugins can be used for the following categories:
meter: PV, battery, grid, meterscharger: Wallboxes, Smart switches, Heat pumps, heating rodsvehicle: Vehiclestariff: Tariffs, forecastscircuit: Load management
Additionally, plugins can also be used for the endpoints described in Messaging for sending lifecycle events.
Overview
Section titled “Overview”Plugins
Section titled “Plugins”- GPIO Plugin - Plugin for direct access to GPIO pins (Linux only).
- Go Plugin - Plugin that provides or receives values via a Go script.
- HTTP Plugin - Plugin that communicates with end devices via HTTP API.
- JavaScript Plugin - Plugin that provides or receives values via a JavaScript script.
- Modbus Plugin - Plugin for reading from a Modbus-capable device.
- MQTT Plugin - Plugin for indirectly communicating with MQTT-capable devices via MQTT.
- Prometheus Plugin - Plugin for reading metrics from Prometheus using PromQL.
- Shell Plugin - Plugin that can execute a shell script to extract data or receive data for writing.
- SMA/Speedwire Plugin - Plugin specifically for SMA devices that can communicate with the Speedwire protocol.
- Websocket Plugin - Plugin for receiving device data via its own web server. Can only be used for reading data.
Helpers
Section titled “Helpers”- Calc Plugin - Meta-plugin for arithmetically linking outputs from other plugins.
- Combined Plugin - Meta-plugin specifically for
chargerto combine the boolean status values for the connected (plugged) and charging (charging) state into a single charging status. - Const Plugin - Special plugin that simply returns a constant value.
- Error Plugin - Special plugin that returns a known error value.
- Convert Plugin - Meta-plugin for data type conversion when writing (e.g., float to int).
- Delta Plugin - Meta-plugin for converting absolute values to delta/increment values when writing.
- Ignore Plugin - Meta-plugin for suppressing specific error messages.
- Map Plugin - Meta-plugin for translating integer values (e.g., device-specific modes to evcc modes).
- Meter Plugin - Plugin to use another meter as a data source.
- Sequence Plugin - Meta-plugin for sequential execution of multiple write operations.
- Sleep Plugin - Helper plugin for delaying actions (usually used with Sequence).
- Switch Plugin - Meta-plugin for conditional write operations based on input values (like switch/case).
- Valid Plugin - Meta-plugin for providing plugin values based on boolean validation.
- Watchdog Plugin - Meta-plugin for automatically repeating write operations at regular intervals.
Syntax
Section titled “Syntax”Each plugin has an individual configuration schema. It’s important to know whether the plugin is used in a reading or writing context. Some configuration parameters only make sense in a reading context, others only when used in writing mode.
For example, the following configuration can be used to integrate an MQTT plugin as a meter, where the current power consumption is read via the specified MQTT topic:
meters: - name: imsys type: custom power: source: mqtt topic: "home/current/imsys/chn2/raw"The plugin configuration schema always has the following structure:
- name: <name> type: custom <attr1>: source: <plugin> <p-attr1>: ... <p-attr2>: ... .... <attr2>: ....Where <name> stands for the device name, <attr1> and <attr2> for one of the device-specific attributes described below, <plugin> for the plugin type and <p-attr1>, <p-attr2> for plugin-specific configurations (e.g. source, topic for plugins of type mqtt)
Reading
Section titled “Reading”When reading data using a plugin, so-called pipelines can be used. These allow data to be extracted in a fine-grained manner from the plugin’s output. This makes it possible to process complex data structures such as JSON or XML and filter out the required information. Possible parameters for data extraction are:
regex: A regular expression to extract values from the received text.jq: A jq-expression to extract values from JSON structures. The full syntax and possibilities can be found in the jq documentation.quote: Boolean value that wraps the input data in quotes before passing it to jq. This allows jq to process unquoted strings (e.g. from MQTT). For an MQTT value likeCharging, you can usequote: trueandjq: '. == "Charging"'.unpack: Converts values from other number representations, e.g.hex.decode: Decodes binary formats likeuint32,float32etc.
Known Error Values
Section titled “Known Error Values”HTTP, MQTT, and Websocket plugins can return special error strings. evcc recognises these and converts them into internal error codes instead of treating them as data. This is useful e.g. for custom vehicle integrations where the data source knows the vehicle’s state.
ErrAsleep— Vehicle is asleep. evcc may choose to wake up the vehicle and retry.ErrMustRetry— Operation should be retried (e.g. due to rate limiting).ErrNotAvailable— Value is not available. evcc treats this as a permanent error until the next restart.
If a plugin returns the string ErrAsleep as its response, evcc generates the corresponding internal error.
The Error Plugin uses the same mechanism to return a fixed error value as a constant.
Writing
Section titled “Writing”When writing, parameters in the configuration can be replaced by placeholders.
The data is provided in the form ${var[:format]}.
If format is not specified, the data is provided in the standard %v Go format.
The variables are replaced with the corresponding value before the plugin is executed.
Additionally, all functions of the Go Template Library can be used to perform more complex data transformations.
Depending on the device (meter, charger or vehicle), different attributes can be read or set with plugins.
Power meters are configured in the configuration section meters.
Meters defined under meters: can be used at various places within the site configuration:
grid: Grid meterpv: PV meterbattery: Home battery metercharge: Meter for the charging power of the wallboxaux: Consumption meter for intelligent consumersext: Additional meter, e.g. for load management or data collection
power is the only mandatory attribute that must be present in every meter definition, all other attributes are optional.
However, not all meter types support all plugin attributes:
limitsocandbatterymodeare used exclusively for battery meters (i.e. formeterreferenced insite.battery).currents,voltagesandpowersare phase attributes that must be configured with exactly three plugin configurations each (in a YAML array) and can be used for grid meters (grid) and wallboxes (charge).
The following tables contain all attributes that can be provided by plugins when configured for meter.
When using the plugins, it’s also important that they return the correct data type.
To convert to the required data type, the pipelines described in Reading can be used.
| Attribute | Type | Required | Context | Description |
|---|---|---|---|---|
| power | float | yes | all | Current power in W |
| energy | float | no | all | Meter reading in kWh |
| maxpower | int | no | pv (hybrid) | Maximum AC power in W |
| soc | int | no | battery | State of charge in % |
| capacity | float | no | battery | Capacity in kWh |
| powers | [float,float,float] | no | all | Phase powers in W. For sign detection of unsigned currents. |
| currents | [float,float,float] | no | all | Phase currents in A. For detecting active phases. |
| voltages | [float,float,float] | no | all | Phase voltages in V. For connection detection (1p/3p). |
Example
In this example, the configuration of a meter is queried for the current electrical grid power via an HTTP call:
meters: - name: volkszaehler type: custom power: source: http uri: http://zaehler.network.local:8080/api/data.json?from=now jq: .data.tuples[0][1]
site: meters: grid: volkszaehler ... ...In addition to the attributes that plugins provide for reading evaluation, the following attributes are used by evcc to trigger actions:
| Attribute | Type | Required | Context | Description |
|---|---|---|---|---|
| limitsoc | int | no | battery | Set charging target for battery in %. The charging target is calculated from the configured MinSoc, MaxSoc and the current state of charge (attribute soc). |
| batterymode | int | no | battery | Set charging mode directly (1: normal, 2: hold, 3: charge) |
Charger
Section titled “Charger”Chargers of type: custom have the following attributes that can be read:
| Attribute | Type | Required | Description |
|---|---|---|---|
| status | string | yes | Status (A..F) |
| enabled | bool | yes | Is charging enabled? |
| power | float | no | Charging power in W |
| energy | float | no | Meter reading in kWh |
| identify | string | no | Current RFID identifier |
| soc | int | no | State of charge in % |
| limitsoc | int | no | Charge limit in % |
| temp | float | no | Current temperature in °C (heating, alias for soc) |
| limittemp | int | no | Temperature limit in °C (heating, alias for limitsoc) |
| finishtime | string | no | Estimated charging finish time (RFC3339, Go duration, Unix timestamp, or remaining seconds) |
| phases | int | no | Number of physical phases (1..3) |
| powers | [float,float,float] | no | Phase powers in W. For sign detection of unsigned currents. |
| currents | [float,float,float] | no | Phase currents in A. For detecting active phases. |
| voltages | [float,float,float] | no | Phase voltages in V. For connection detection (1p/3p). |
For heat-pump-specific charger types (heatpump, sgready, sgready-relay), different plugin attributes apply, see Heat pumps.
General Configuration Options
Section titled “General Configuration Options”In addition to plugin attributes, the following configuration options can be set directly on the charger:
| Attribute | Type | Required | Description |
|---|---|---|---|
| icon | string | no | Icon for display in the user interface |
| features | []string | no | Feature flags for special charger properties (see below) |
| standbypower | int | no | Standby power in W (for switchsocket type) |
Feature Flags
Section titled “Feature Flags”The features array can be used to activate special charger properties:
| Feature | Description |
|---|---|
| integrateddevice | No vehicle selection. Device runs without a connected vehicle and without charging sessions (e.g. heat pump, heating rod, permanently installed consumer). |
| heating | Treat device as heating: SOC and limits are displayed in °C instead of %. |
| continuous | Device keeps running in its own normal operation when “disabled”. The UI shows “Normal operation” instead of “Standby”. A request to increase power (e.g. on PV surplus or cheap grid power) is labelled “Boost”. |
| switchdevice | Device can only be switched on/off (no continuous current control). Min/max current settings and the Min+PV mode are hidden. |
Common Combinations
Section titled “Common Combinations”You can use the following combinations as a starting point for your own type: custom configurations.
They mirror the preconfigured templates in evcc.
Electric heater:
features: - integrateddevice - heatingSocket:
features: - switchdevice - integrateddevice # optional, when the socket drives a fixed load - heating # optional, when it controls a heating deviceHeat pump:
features: - integrateddevice - heating - continuous - switchdevice # optional, when no current control is available (SG Ready)Example
This example shows how to query the charging status (charging/not charging) of a charger via the Modbus plugin:
chargers: - name: icharge type: custom features: - integrateddevice enabled: source: modbus id: 4711 uri: modbus.local:502 rtu: false register: address: 100 type: holding decode: uint16In addition to read-only values, actions can also be triggered or configuration values set via plugins:
| Attribute | Type | Required | Description |
|---|---|---|---|
| enable | bool | yes | Enable / disable charging |
| maxcurrent | int | yes | Set maximum charging current in A |
| maxcurrentmillis | float | no | Set maximum charging current in A (with decimals) |
| phases1p3p | int | no | Perform phase switching (requires tos: true) |
| wakeup | bool | no | Wake up vehicle |
Example
This example switches a Tasmota socket via an MQTT message:
chargers: - name: unu-charger type: custom enable: source: mqtt broker: mosquitto.local:883 topic: cmd/unu-switch/Power payload: ONHeat Pumps
Section titled “Heat Pumps”Heat pumps and similar heating devices use dedicated charger types, each with its own plugin attributes. The full setup is described under Heat pumps, heating rods.
All three types share the following optional measurement attributes:
| Attribute | Type | Required | Description |
|---|---|---|---|
| power | float | no | Current power in W |
| energy | float | no | Meter reading in kWh |
| temp | float | no | Current temperature in °C |
| limittemp | int | no | Device-internal temperature limit in °C |
type: heatpump: heat pump with power setpoint.
| Attribute | Type | Required | Description |
|---|---|---|---|
| setmaxpower | int | yes | Set maximum heating power in W |
| getmaxpower | float | no | Current maximum heating power in W |
type: sgready: heat pump with SG-Ready interface.
| Attribute | Type | Required | Description |
|---|---|---|---|
| setmode | int | yes | Change SG-Ready mode (1: reduced, 2: normal, 3: boost) |
| getmode | int | no | Current SG-Ready mode (1, 2, 3) |
| setmaxpower | int | no | Set maximum heating power in W |
type: sgready-relay: heat pump controlled via relay contacts.
Sub-chargers are referenced by type instead of via plugins.
| Attribute | Type | Required | Description |
|---|---|---|---|
| boost | charger-typed | yes | Relay for the SG-Ready boost contact |
| dim | charger-typed | no | Relay for the SG-Ready dim contact |
Vehicle
Section titled “Vehicle”Vehicle parameters can also be read via plugins.
| Attribute | Type | Required | Description |
|---|---|---|---|
| soc | int | yes | State of charge in % |
| limitsoc | int | no | Charge limit in % |
| status | string | no | Status (A..F) |
| range | int | no | Range in km |
| odometer | int | no | Odometer reading in km |
| climater | bool | no | Climate control active? |
| getmaxcurrent | float | no | Maximum charging current in A |
| finishtime | string | no | Estimated charging finish time (RFC3339, Go duration, Unix timestamp, or remaining seconds) |
General Configuration Options
Section titled “General Configuration Options”The following configuration options can be set directly on the vehicle:
| Attribute | Type | Required | Description |
|---|---|---|---|
| title | string | no | Display name of the vehicle in the user interface |
| icon | string | no | Icon for display in the user interface |
| capacity | float | no | Battery capacity in kWh |
| features | []string | no | Feature flags for special vehicle properties (see below) |
Feature Flags
Section titled “Feature Flags”| Feature | Description |
|---|---|
| coarsecurrent | Vehicle accepts charging current only in whole 1 A steps. The control logic is constrained to coarse 1 A steps even when the charger could regulate more finely. |
| streaming | Vehicle pushes data instead of being polled (e.g. BMW Cardata). SOC updates outside active charging are treated as reliable. |
| welcomecharge | Vehicle expects the wallbox to be active on connect to register the link as working. Otherwise it reports an error. |
Example
In the following example, the current range of the vehicle is read from MQTT messages:
vehicles: - name: mazda type: custom title: Green Mazda capacity: 50 features: - coarsecurrent range: source: mqtt topic: mazda2mqtt/c53/chargeInfo/drivingRangeKmAdditionally, special commands can be sent to the vehicle via plugins:
| Attribute | Type | Required | Description |
|---|---|---|---|
| wakeup | bool | no | Wake up vehicle |
| chargeenable | bool | no | Start/stop charging process |
| maxcurrent | int | no | Set maximum charging current in A |
Example
To wake up a car via an HTTP ping to send further queries, the HTTP plugin can be used as in the following example:
vehicles: - name: model-y type: custom wakeup: source: http uri: http://teslalogger.local:5000/command/08154711/wake_upCharge Mode on Vehicle Identification
Section titled “Charge Mode on Vehicle Identification”For user-defined vehicles, the charge mode can be configured with onIdentify to be set automatically when the vehicle is identified.
This is useful when you want the desired charge mode to be set automatically as soon as the vehicle is detected.
Example:
vehicles: - name: my-car type: custom soc: source: mqtt topic: car/soc onIdentify: mode: pvAvailable modes are: off, now, minpv, pv.
Tariffs & Forecasts
Section titled “Tariffs & Forecasts”See Tariffs & Forecasts > Custom Plugin for the full configuration.
Feature Flags
Section titled “Feature Flags”| Feature | Description |
|---|---|
| average | Smooths fine-grained price slots (e.g. 15-minute values) into hourly averages. |
| cacheable | Persists fetched values. Used as fallback after a restart or provider outage (up to 24 hours). |
tariffs: grid: type: custom features: - cacheable # ... additional attributesLoad Management
Section titled “Load Management”Messaging
Section titled “Messaging”Plugins
Section titled “Plugins”The following plugins are available and can be configured for the above-described attributes to enable flexible integration with various systems.
GPIO read write
Section titled “GPIO ”The gpio plugin enables direct access to GPIO pins (General Purpose Input/Output) on Linux systems.
It is particularly suitable for Raspberry Pi and similar single-board computers.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| function | string | yes | Mode: read (input) or write (output) |
| pin | int | yes | Pin number (BCM numbering, e.g. GPIO 17) |
How it works:
- Reading (
function: read): Reads the state of a GPIO pin as a boolean value (true= HIGH,false= LOW) - Writing (
function: write): Sets a GPIO pin to HIGH (true) or LOW (false)
Pin numbering follows the BCM scheme (Broadcom numbers, not the physical pin position). For a Raspberry Pi pinout, see e.g. pinout.xyz.
Reading Example:
source: gpiofunction: readpin: 17 # BCM pin numberWriting Example:
source: gpiofunction: writepin: 27 # BCM pin numberGo read write
Section titled “Go ”The go plugin uses the Yaegi interpreter to execute Go code at runtime.
It’s particularly useful for type-safe calculations and complex data processing logic.
Available Go Standard Libraries
Section titled “Available Go Standard Libraries”The following Go packages are automatically available and don’t need to be imported:
fmt- Formatted I/Omath- Mathematical functionsstrings- String manipulationtime- Time and date functions
Reading Example:
source: goscript: | res := 500.0 res * 2 // returns 1000.0Example with Time Functions:
source: goscript: | hour := time.Now().Hour() price := 50.0 // Night tariff if hour >= 9 && hour < 17 { price = 100.0 // Tariff price during business hours } priceExample with String Processing:
source: goscript: | text := "hello world" strings.ToUpper(text) // returns "HELLO WORLD"When the go plugin is used for writing, the value to be written is passed to the script as a variable:
Writing Example:
charger: - type: custom maxcurrent: source: go script: | fmt.Printf("Setting charge current: %d A\n", maxcurrent) // maxcurrent variable is automatically availableInput and Output Transformations
Section titled “Input and Output Transformations”The go and js plugins support in and out parameters to use values from other sources as variables in the script or to forward the script result to other plugins.
Input Transformations (in)
Section titled “Input Transformations (in)”The in parameter allows you to use values from other sources as variables in your script.
Each entry requires name (variable name in the script), type (bool, int, float, string) and config (plugin configuration).
This example shows conditional logic that cannot be achieved with simple Calc operations:
power: source: go script: | // Power based on SoC and standby power := 5000.0 // normal if standby { power = 0.0 // no load in standby } else if soc < 20.0 { power = 1000.0 // low } power in: - name: soc type: float config: source: const value: 85.0 - name: standby type: bool config: source: const value: falseOutput Transformations (out)
Section titled “Output Transformations (out)”The out parameter forwards the script result to other plugins.
This is particularly useful in a writing context, e.g. when the script result should be further processed via MQTT or HTTP.
Each entry requires name, type and config — analogous to in.
chargers: - name: smart-heater type: custom maxcurrent: source: go script: | watts := maxcurrent * 230 watts out: - name: watts type: float config: source: mqtt topic: heater/target_powerHTTP read write
Section titled “HTTP ”The http plugin performs HTTP calls to read or update data.
It also includes the ability to read or perform simple transformations on JSON data structures via jq queries (e.g. for REST APIs).
The full functionality can be found in the official jq documentation.
Authentication methods are basic, bearer and digest.
The names of the respective parameters can be found here.
Authentication
Section titled “Authentication”Various authentication methods are available for HTTP requests:
Basic Authentication:
auth: type: basic user: <username> password: <password>Bearer Token (e.g. for JWT):
auth: type: bearer token: <token>Digest Authentication:
auth: type: digest user: <username> password: <password>Custom Authentication:
For more complex authentication scenarios, custom authentication plugins can be developed.
These are integrated via the source parameter:
auth: source: <plugin-name> user: <username> password: <password> # additional plugin-specific parametersThis allows integration of devices with special authentication requirements without having to modify the entire HTTP plugin code.
Reading Example:
source: httpuri: https://volkszaehler/api/data/<uuid>.json?from=nowmethod: GET # default HTTP methodheaders: - content-type: application/jsonauth: # basic authentication type: basic user: foo password: barinsecure: false # set to true to trust self-signed certificatesjq: .data.tuples[0][1] # parse response jsonscale: 0.001 # factor applied to result, e.g. for kW to W conversioncache: 60s # response cache durationtimeout: 10s # timeout in golang duration format, see https://golang.org/pkg/time/#ParseDurationsource: httpuri: http://charger/statusjq: .total_power > 10 # Converts a json integer to a boolean valueWriting Example:
body: %v # only applicable for PUT or POST requestsenable: source: http uri: "http://charger/relay/0?turn={{if .enable}}on{{else}}off{{end}}"JavaScript read write
Section titled “JavaScript ”evcc integrates a JavaScript interpreter with the Underscore.js library, which is directly accessible via _., e.g. _.random(0,5).
The js plugin can execute JavaScript code via the script parameter. Very helpful for rapid prototyping:
Reading Example:
source: jsscript: | var res = 500; 2 * res; // returns 1000When the js plugin is used for writing, the value to be written is passed to the script as a variable:
Writing Example:
charger: - type: custom maxcurrent: source: js script: | console.log(maxcurrent);The js plugin supports the same input and output transformations (in/out) as the go plugin.
Modbus read write
Section titled “Modbus ”The modbus plugin can read data from any Modbus-capable device or SunSpec-compatible inverter.
Many power meters are already pre-configured (see MBMD Supported Devices).
It’s also possible to write Modbus registers to integrate additional wallboxes.
Example:
source: modbusid: 1uri: 192.168.1.10:502register: address: 300 type: holding decode: uint16See the Modbus Documentation for more details.
MQTT read write
Section titled “MQTT ”The mqtt plugin enables reading values via MQTT topics.
This is particularly useful for power meters, e.g. when they already provide their data via MQTT.
See the MBMD Documentation for an example of how to get Modbus measurement data into MQTT.
Parameters (Reading):
| Parameter | Type | Required | Description |
|---|---|---|---|
| topic | string | yes | MQTT topic to read from |
| timeout | duration | no | Maximum age of received values |
| scale | float | no | Scaling factor for result (e.g. 0.001 for Wh to kWh conversion) |
The plugin returns an error if no new value has been received within the timeout duration.
If timeout is not set, values of any age are accepted once the first message has been received.
It is recommended to set a timeout to detect when the source is no longer providing current data.
For data extraction, the pipeline parameters described under Reading are available (regex, jq, quote, etc.).
Reading Example:
source: mqtttopic: mbmd/sdm1-1/Powertimeout: 30s # don't accept values older than timeoutscale: 0.001 # factor applied to result, e.g. for Wh to kWh conversionParameters (Writing):
| Parameter | Type | Required | Description |
|---|---|---|---|
| topic | string | yes | MQTT topic to write to |
| payload | string | no | Payload template (uses value in default format if not set) |
For write access, the data is provided with the payload attribute.
If this parameter is missing from the configuration, the value is written in the default format.
Writing Example:
source: mqtttopic: mbmd/charger/maxcurrentpayload: ${var:%d}Prometheus read
Section titled “Prometheus ”The prometheus plugin reads metrics from a Prometheus instance using PromQL queries.
This is useful when monitoring data is already available in Prometheus and should be used in evcc.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| uri | string | yes | Prometheus server URL |
| query | string | yes | PromQL query |
| timeout | duration | no | Timeout (default: 2 minutes) |
Supported query results:
- Scalar: A single numerical value
- Vector: A vector with exactly one metric entry
Example:
power: source: prometheus uri: http://prometheus.local:9090 query: "sum(household_power_watts)" timeout: 30sExample with time range:
energy: source: prometheus uri: http://prometheus.local:9090 query: "increase(energy_total_kwh[1h])"The query must return a single numerical value. For vector results, exactly one metric must be included.
Shell Script read write
Section titled “Shell Script ”The script plugin executes external scripts to read or update data. The plugin is useful for integrating any kind of external functionality.
Reading Example:
source: scriptcmd: /bin/bash -c "cat /dev/urandom"timeout: 5sWriting Example:
source: scriptcmd: /home/user/my-script.sh ${enable:%b} # format boolean enable as 0/1timeout: 5sSMA/Speedwire read
Section titled “SMA/Speedwire ”The sma plugin provides an interface to SMA devices that support the Speedwire protocol.
Reading Example:
source: smauri: 192.168.4.51 # alternative to serialserial: 123456 # alternative to urivalue: ActivePowerPlus # ID of value to readpassword: "0000" # optional (default: 0000)interface: eth0 # optionalscale: 1 # optional scale factor for valueSupported values for value can be found in the diagnostic output using the evcc meter command (with configured SMA meter devices).
All possible values can be found as constants here (use the constant name for value).
Websocket read
Section titled “Websocket ”The websocket plugin provides a WebSocket listener.
It also includes the ability to read or parse JSON data structures via jq-like queries.
This can be used, for example, to receive data from Volkszähler’s push server.
For data extraction, the pipeline parameters described in Reading are available (regex, jq, quote, etc.).
Reading Example:
source: httpuri: ws://<volkszaehler host:port>/socketjq: .data | select(.uuid=="<uuid>") .tuples[0][1] # parse message jsonscale: 0.001 # factor applied to result, e.g. for Wh to kWh conversiontimeout: 30s # error if no update received in 30 secondsHelpers
Section titled “Helpers”Calc read
Section titled “Calc ”The calc plugin allows mathematical processing of multiple individual values:
Reading Example:
source: calcadd:- source: ... ...- source: ... ...source: calcmul:- source: calc sign: source: ... (power) ...- source: ... (current) ...The basic arithmetic operations addition (add), multiplication (mul), division (div), sign inversion (sign), absolute value (abs), minimum value (min) and maximum value (max) are supported as operands.
With scale: -1 on one of the values, simple subtraction can be performed, with scale: 0.001 division, e.g. for converting kWh to Wh.
With sign: (every positive number becomes +1, every negative number becomes -1, 0 remains 0), signs can be transferred to other values (in conjunction with mul).
E.g. to transfer the “direction” of power (feed-in or consumption) to the measured currents for meters.
With abs:, the absolute value of a number is calculated.
With min: and max: the minimum value respectively the maximum value will be calculated.
The calc plugin is helpful for e.g.
- Summing power values from individual PV strings (addition)
- Calculating apparent power from voltage and current (multiplication)
- Combining separate power values for import and export into a signed single value (subtraction).
- Calculating percentage fill levels (division)
- Determining the correct direction of current flow (sign)
- Eliminating known offsets (addition with
constplugin)
Combined read
Section titled “Combined ”The combined status plugin is used to convert mixed boolean status values of Plugged (connected) / Charging (charging) into an evcc-compatible charging status of A..F.
It’s used, for example, with an OpenWB MQTT integration.
Reading Example:
source: combinedplugged: source: mqtt topic: openWB/lp/1/boolPlugStatcharging: source: mqtt topic: openWB/lp/1/boolChargeStatConst read
Section titled “Const ”The const plugin returns a constant value.
It’s suitable, for example, to apply fixed correction values (offset) to a variable value in conjunction with the calc plugin or to simulate measurement and status values for testing purposes.
Reading Example:
source: constvalue: -16247Error read
Section titled “Error ”The error plugin always returns a known error value.
It is useful to explicitly mark an unimplemented attribute as not available.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| error | string | yes | Error value (ErrAsleep, ErrMustRetry or ErrNotAvailable) |
Example:
soc: source: error error: ErrNotAvailableConvert write
Section titled “Convert ”The convert plugin converts data types when writing.
It is used when a plugin expects a different data type than evcc provides.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| convert | string | yes | Conversion type |
| set | config | yes | Plugin for writing after conversion |
Supported conversions:
| Conversion | Description |
|---|---|
| float2int | Float64 → Int64 (decimal places are truncated) |
| int2float | Int64 → Float64 |
| int2bytes | Int64 → Byte array (Big Endian, 8 bytes) |
Example (evcc provides float, device expects int):
limitsoc: source: convert convert: float2int set: source: modbus uri: 192.168.1.10:502 id: 1 register: address: 41009 type: writesingle encoding: uint16In this example, evcc converts a float value like 85.5 to 85 before writing it to the modbus register.
Delta write
Section titled “Delta ”The delta plugin converts absolute values to delta/increment values.
It’s used for devices that add written values to an internal sum instead of setting them directly.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| get | config | no | Plugin for reading the current total from device |
| set | config | yes | Plugin for writing the calculated delta |
How it works:
- Input value is received (e.g.,
1000) - If
getis configured, the current total is read from the device - Delta is calculated:
delta = new_value - current_total - Delta is written via the
setplugin - Internal state is updated
Without the get parameter, the plugin tracks the total internally (starts at 0).
When evcc restarts, synchronisation with the device is lost.
Therefore, it’s recommended to configure get if the device provides a readable total register.
Supported data types: int64, float64
Use case:
Some heat pumps (e.g., Ochsner) have registers that expect delta values instead of absolute values.
When writing 500, the device adds 500 W to the internal value instead of setting it to 500 W.
To increase from 1000 W to 1500 W, you must write +500.
To decrease, negative values are written (e.g., -300).
Writing Example:
setmaxpower: source: delta get: # Read current total from device source: modbus uri: 192.168.1.50:502 id: 50 register: address: 2012 # Device's internal sum register type: input decode: uint16 set: # Write calculated delta source: modbus uri: 192.168.1.50:502 id: 50 register: address: 2201 # Delta register type: writeholding decode: uint16Example with Watchdog:
The delta plugin is often combined with the watchdog plugin when the device requires periodic updates:
setmaxpower: source: watchdog timeout: 60s # Resend every 30 seconds set: source: delta # Convert absolute values to deltas get: # Read current total source: modbus uri: 192.168.1.50:502 id: 50 register: address: 2012 # Total register type: input decode: uint16 set: # Write delta source: modbus uri: 192.168.1.50:502 id: 50 register: address: 2201 # Delta register type: writeholding decode: uint16Ignore write
Section titled “Ignore ”The ignore plugin suppresses specific error messages when writing.
It is used when a device returns harmless errors that can be ignored.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| error | string | yes | Error text prefix to ignore |
| set | config | yes | Plugin for writing |
How it works:
- The nested
setplugin is executed - If an error occurs, it checks whether the error message starts with the
errorstring - If yes, the error is ignored and success is returned
- If no, the error is passed through normally
Supported data types: int64, float64, bool, []byte
Example:
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 this example, the device returns a harmless modbus error that is ignored.
Map read write
Section titled “Map ”The map plugin translates integer values to other integer values using a lookup table.
It is often used to convert device-specific values to evcc standard values and vice versa.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| values | map[int64]int64 | yes | Lookup table with input → output mapping |
| get | config | no | Plugin for reading (only required when reading) |
| set | config | no | Plugin for writing (only required when writing) |
How it works:
When reading:
getplugin returns a value (e.g.,0)- Value is looked up in the
valuestable - The mapped value is returned (e.g.,
0→2)
When writing:
- Input value is received (e.g.,
3) - Value is looked up in the
valuestable - The mapped value is passed to the
setplugin (e.g.,3→6)
If no matching value is found in the table, an error occurs.
Supported data types: int64 (integer values only)
Reading example (device value → evcc):
getmode: source: map values: 0: 2 # Device "Free" → evcc "normal" 1: 1 # Device "Forced off" → evcc "reduced" 2: 3 # Device "Recommended on" → evcc "boost" 3: 3 # Device "Forced on" → evcc "boost" get: source: modbus uri: 192.168.1.10:502 id: 1 register: address: 55 type: holding encoding: int16Writing example (evcc → device value):
setmode: source: map values: 1: 1 # evcc "reduced" → Device "Forced off" 2: 0 # evcc "normal" → Device "Free" 3: 3 # evcc "boost" → Device "Forced on" set: source: modbus uri: 192.168.1.10:502 id: 1 register: address: 55 type: writeholding encoding: int16Meter read
Section titled “Meter ”The meter plugin allows using another meter as a data source.
This is useful when you want to use an existing device for multiple measurements or when you need different methods of a device for different attributes.
The config section contains the complete template configuration of the meter to be embedded.
Reading Example:
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 this example, a Shelly 1PM device is used as a data source for power and energy of a battery, while the state of charge (SoC) is retrieved via MQTT.
Sequence write
Section titled “Sequence ”The sequence plugin executes multiple write operations sequentially.
All nested plugins receive the same input value and are executed in the defined order.
Execution stops immediately on error.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| set | [config] | yes | Array of nested plugin configurations |
How it works:
- Input value is received
- Each plugin in the
setlist is called sequentially with this value - On error, the sequence is aborted and the error is returned
- Successful execution means all plugins executed successfully
Supported data types: int64, float64, bool
Use cases:
- Execute multiple HTTP calls sequentially
- Combine with
sleepplugin for time-delayed actions - Write multiple modbus registers simultaneously
- Propagate values to multiple targets
Example 1: Multiple HTTP calls
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"}'Example 2: Combination with 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}"Flow for batterymode: 1 (normal):
- Outer
sequencereceives value1 - First step:
switchchecks value1- Case
1matches → HTTP call to/api/modewith bodyautomatic
- Case
- Second step:
mqttsends message tohome/battery/statuswith payloadmode_1 - Done
Flow for batterymode: 3 (charge):
- Outer
sequencereceives value3 - First step:
switchchecks value3- Case
3matches → Innersequenceis executed:- Wait 1 second (
sleep) - HTTP call to
/api/chargewith body5000
- Wait 1 second (
- Case
- Second step:
mqttsends message tohome/battery/statuswith payloadmode_3 - Done
The value flows through all plugins, with switch executing different actions based on the value and mqtt always notifying at the end.
Sleep write
Section titled “Sleep ”The sleep plugin adds a delay.
Typically used within a sequence plugin to create time intervals between actions.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| duration | duration | yes | Wait time (e.g., 1s, 500ms, 0s for no delay) |
Example:
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 write
Section titled “Switch ”The switch plugin performs conditional write operations, similar to a switch/case statement in programming languages.
Based on the input value, the corresponding action is executed.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| switch | [case] | yes | Array of cases with case and set configuration |
| default | config | no | Fallback plugin if no case matches |
How it works:
- Input value is compared with the
casevalues - On match, the corresponding
setplugin is executed - If no case matches and
defaultis defined, it is executed - If no case matches and no
defaultis defined, an error occurs
Supported data types: int64 (integer values only)
Example:
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 read
Section titled “Valid ”The valid plugin allows providing plugin values based on boolean validation.
It separates the validity of a value from its actual content.
If the validation returns false, the value is considered unavailable.
This is particularly useful for integrations like ioBroker that provide validity and value separately.
Reading Example:
source: validvalid: source: mqtt topic: iobroker/wallbox/power/validvalue: source: mqtt topic: iobroker/wallbox/power/valueIn this example, the value is only used when the valid topic returns true.
If it returns false, the value is marked as unavailable.
Watchdog write
Section titled “Watchdog ”The watchdog plugin is a wrapper plugin that automatically repeats write operations at regular intervals.
Some devices (e.g. battery storage systems, inverters) expect control commands to be repeated regularly to stay active.
The watchdog plugin monitors write operations and automatically repeats them at half the configured timeout interval.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| timeout | duration | yes | Time interval for repetitions (value is rewritten every timeout/2) |
| reset | string | [string] | no | Value(s) at which repetitions are stopped |
| initial | string | no | Value that is written once at startup |
| defer | bool | no | Defers updates instead of executing them immediately (default: false) |
| set | config | yes | Nested plugin for the actual write operation |
How it works:
- Start: If
initialis configured, this value is written once at startup - Write: When a value is written, the plugin checks whether it is in the
resetlist - Watchdog active: If the value is not in
reset, the watchdog starts and automatically rewrites the value everytimeout/2seconds - Watchdog stops: If the value is in
reset, no repetitions are performed
reset parameter:
- Defines values at which the watchdog is stopped
- Can be a single value (
reset: 0) or multiple values (reset: [0, 1]) - Typically used for “safe” or “default” states that don’t need continuous repetition
initial parameter:
- Optional value that is written once when the plugin starts
- Useful for setting a defined initial state
- Executed before all other write operations
defer parameter:
- Ensures that timeouts between updates are respected
- The watchdog is stopped during the delay and restarted with the new value after expiry
- Useful when devices require a minimum wait time between mode changes
- The delay is calculated based on the time since the last update
- Reset values are always written immediately (without delay)
Supported data types: int64, float64, bool
Example Write:
source: watchdogtimeout: 60sreset: 0set: source: modbus uri: 192.168.1.10:502 id: 1 register: address: 100 type: writemultiple encoding: uint16In this example, values are automatically repeated every 30 s, except when the value 0 is written.
Flow example with timeout: 60s, reset: 0:
- Plugin starts
- Write value
100→ Watchdog runs, value is repeated every 30 s - After 2 minutes: Value
100has been written 4x (0s, 30s, 60s, 90s, 120s) - Write value
200→ Watchdog continues running, now with new value200every 30 s - Write value
0→ Watchdog stops (since0is defined inreset) - No further repetitions until a new value !=
0is written
Example with battery control (batterymode uses values 1=normal, 2=hold, 3=charge):
batterymode: source: watchdog timeout: 60s reset: 1 # Stop repetitions in normal operation set: source: switch switch: - case: 1 # normal set: source: modbus # ... Modbus configuration for normal operation - case: 2 # hold set: source: modbus # ... Modbus configuration for hold mode - case: 3 # charge set: source: modbus # ... Modbus configuration for charge mode