Skip to content
EN | DE

User-defined Devices

When creating a charger, heater, grid meter, battery, solar system, other consumer, vehicle, tariff or notification service, you can pick the User-defined device option from the device type list and describe your own logic based on the plugin system.

That way you can integrate devices that aren’t covered by a built-in template, e.g. read the current power from an HTTP endpoint, or write a target current via Modbus.

In the UI, every device type lists a User-defined device entry in the template selector. Picking it opens the editor for your own configuration. A device with type: custom is created by default. The type can be overridden with another value when needed (e.g. type: heatpump).

power:
source: mqtt
topic: home/current/imsys/chn2/raw

Alternatively, write the full configuration directly in evcc.yaml with name, type: custom and the attribute block underneath:

meters:
- name: imsys
type: custom
power:
source: mqtt
topic: home/current/imsys/chn2/raw

All other examples on this page use the flat attribute-block form you enter in the UI.

For the list of available plugin sources (http, mqtt, modbus, …) and helpers (calc, map, watchdog, …) see the plugins reference.

Every user-defined device is described by three kinds of fields:

  • Read attributes — plugins evcc polls to obtain a value (e.g. power, soc, status).
  • Write attributes — plugins evcc invokes to set a value or trigger an action (e.g. enable, maxcurrent, wakeup). The value to be written is available in the plugin.
  • Featuresfeatures list toggling non-default behaviour. Available flags depend on the device type.

Generic shape:

# read attributes
power:
source: http
uri: http://meter.local/power
soc:
source: mqtt
topic: battery/soc
# write attributes
enable:
source: http
uri: "http://charger/relay?turn={{if .enable}}on{{else}}off{{end}}"
maxcurrent:
source: mqtt
topic: charger/maxcurrent
payload: ${maxcurrent:%d}
# features
features:
- heating
- integrateddevice

The available attribute names and feature flags differ per device type and are listed in the sections below.

Power meters are configured in the meters section. Meters defined under meters: can be referenced from site:

  • grid: Grid meter
  • pv: PV meter
  • battery: Home battery meter
  • charge: Meter for the charging power of the wallbox
  • aux: Consumption meter for intelligent consumers
  • ext: Additional meter, e.g. for load management or data collection

power is the only required attribute. Not all meter roles support all attributes:

  • limitsoc and batterymode are used exclusively for battery meters (referenced from site.battery).
  • currents, voltages and powers are phase attributes that must be configured with exactly three plugin entries each (as a YAML array) and apply to grid meters (grid) and wallboxes (charge).

Return the correct data type from each plugin. To convert, use the reading pipelines.

AttributeTypeRequiredContextDescription
powerfloatyesallCurrent power in W
energyfloatnoallMeter reading in kWh
maxpowerintnopv (hybrid)Maximum AC power in W
socintnobatteryState of charge in %
capacityfloatnobatteryCapacity in kWh
powers[float,float,float]noallPhase powers in W. For sign detection of unsigned currents.
currents[float,float,float]noallPhase currents in A. For detecting active phases.
voltages[float,float,float]noallPhase voltages in V. For connection detection (1p/3p).
AttributeTypeRequiredContextDescription
limitsocintnobatterySet charging target for battery in %. The charging target is calculated from the configured MinSoc, MaxSoc and the current state of charge (attribute soc).
batterymodeintnobatterySet charging mode directly (1: normal, 2: hold, 3: charge)

Read the current grid power from an HTTP endpoint.

power:
source: http
uri: http://zaehler.network.local:8080/api/data.json?from=now
jq: .data.tuples[0][1]

The default type: custom covers wallboxes with continuous current control. For other devices, specialised charger types are described under Switchsocket and Heat pumps.

AttributeTypeRequiredDescription
statusstringyesStatus (A..F)
enabledboolyesIs charging enabled?
powerfloatnoCharging power in W
energyfloatnoMeter reading in kWh
identifystringnoCurrent RFID identifier
socintnoState of charge in %
limitsocintnoCharge limit in %
tempfloatnoCurrent temperature in °C (heating, alias for soc)
limittempintnoTemperature limit in °C (heating, alias for limitsoc)
finishtimestringnoEstimated charging finish time (RFC3339, Go duration, Unix timestamp, or remaining seconds)
phasesintnoNumber of physical phases (1..3)
powers[float,float,float]noPhase powers in W. For sign detection of unsigned currents.
currents[float,float,float]noPhase currents in A. For detecting active phases.
voltages[float,float,float]noPhase voltages in V. For connection detection (1p/3p).
AttributeTypeRequiredDescription
enableboolyesEnable / disable charging
maxcurrentintyesSet maximum charging current in A
maxcurrentmillisfloatnoSet maximum charging current in A (with decimals)
phases1p3pintnoPerform phase switching (requires tos: true)
wakeupboolnoWake up vehicle
FeatureDescription
integrateddeviceNo vehicle selection. Device runs without a connected vehicle and without charging sessions (e.g. heat pump, heating rod, permanently installed consumer).
heatingTreat device as heating: SOC and limits are displayed in °C instead of %.
continuousDevice 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”.
switchdeviceDevice can only be switched on/off (no continuous current control). Min/max current settings and the Min+PV mode are hidden.

Common feature combinations seen in built-in templates:

Electric heater:

features:
- integrateddevice
- heating

Socket:

features:
- switchdevice
- integrateddevice # optional, when the socket drives a fixed load
- heating # optional, when it controls a heating device

Heat pump:

features:
- integrateddevice
- heating
- continuous
- switchdevice # optional, when no current control is available (SG Ready)

Query the charging status of a charger via Modbus.

features:
- integrateddevice
enabled:
source: modbus
id: 4711
uri: modbus.local:502
rtu: false
register:
address: 100
type: holding
decode: uint16

Switch a Tasmota socket via an MQTT message.

enable:
source: mqtt
broker: mosquitto.local:883
topic: cmd/unu-switch/Power
payload: ON

type: switchsocket

For smart sockets and similar relay devices that can only be switched on/off without continuous current control. The charging status is derived from the current power (above standbypower means charging). Full setup details are under Smart switches.

AttributeTypeRequiredDescription
enabledboolyesRead socket state (on/off)
powerfloatyesCurrent power in W
energyfloatnoMeter reading in kWh
socfloatnoState of charge in %
enableboolyesSwitch socket on/off
standbypowerfloatnoPower threshold in W. Above it: charging; below: standby. Negative: static (no metering)

Heat pumps and similar heating devices use dedicated charger types, each with its own attributes. The full setup is described under Heat pumps, electric heaters.

type: heatpump

For inverter-controlled heat pumps that accept a continuous power setpoint over Modbus, HTTP or similar. The target heating power is written directly via setmaxpower.

AttributeTypeRequiredDescription
powerfloatnoCurrent power in W
energyfloatnoMeter reading in kWh
tempfloatnoCurrent temperature in °C
limittempintnoDevice-internal temperature limit in °C
setmaxpowerintyesSet maximum heating power in W
getmaxpowerfloatnoCurrent maximum heating power in W

Vehicle parameters can also be read via plugins.

AttributeTypeRequiredDescription
socintyesState of charge in %
limitsocintnoCharge limit in %
statusstringnoStatus (A..F)
rangeintnoRange in km
odometerintnoOdometer reading in km
climaterboolnoClimate control active?
getmaxcurrentfloatnoMaximum charging current in A
finishtimestringnoEstimated charging finish time (RFC3339, Go duration, Unix timestamp, or remaining seconds)
AttributeTypeRequiredDescription
wakeupboolnoWake up vehicle
chargeenableboolnoStart/stop charging process
maxcurrentintnoSet maximum charging current in A
AttributeTypeRequiredDescription
titlestringnoDisplay name of the vehicle
capacityfloatnoBattery capacity in kWh
iconstringnoIcon shown in the user interface
FeatureDescription
coarsecurrentVehicle 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.
streamingVehicle pushes data instead of being polled (e.g. BMW Cardata). SOC updates outside active charging are treated as reliable.
welcomechargeVehicle expects the wallbox to be active on connect to register the link as working. Otherwise it reports an error.

Read the current range from MQTT messages.

title: Green Mazda # display name (optional)
capacity: 50 # battery capacity in kWh (optional)
features:
- coarsecurrent
range:
source: mqtt
topic: mazda2mqtt/c53/chargeInfo/drivingRangeKm

Wake a car via an HTTP ping before sending further queries.

wakeup:
source: http
uri: http://teslalogger.local:5000/command/08154711/wake_up

onIdentify sets the charge mode automatically when the vehicle is detected.

soc:
source: mqtt
topic: car/soc
onIdentify:
mode: pv

Available modes: off, now, minpv, pv.

A user-defined tariff connects evcc to a custom value source via the plugin mechanism. The tariff attribute selects what the source represents and which unit the values use.

Exactly one of price or forecast must be configured.

AttributeTypeDescription
pricefloatCurrent value. Float returned by the plugin.
forecaststringForecast as JSON string with a list of time periods and values (see schema below). Polled hourly.
AttributeTypeRequiredDescription
tariffstringnoprice (default), co2 or solar. Sets the unit of the returned values: price in configured currency per kWh, CO₂ intensity in g/kWh, solar forecast in W.
chargesfloatnoFixed additional charge per kWh added to every value. Default 0.
taxfloatnoPercentage tax applied to the result, e.g. 0.2 for 20 %. Default 0.
formulastringnoGo expression for a custom calculation, with price, charges and tax in scope. See examples.
intervaldurationnoPolling interval for forecast. Default 1h.
cachedurationnoCache duration for price. Default 15m.
FeatureDescription
averageSmooths fine-grained price slots (e.g. 15-minute values) into hourly averages.
cacheablePersists fetched values. Used as fallback after a restart or provider outage (up to 24 hours).

Current price via HTTP:

price:
source: http
uri: https://example.com/api/price

Forecast via HTTP:

forecast:
source: http
uri: https://api.allinpower.nl/troodon/api/p/spot_market/prices/?product_type=ELK
jq: '[.timestamps, .prices] | transpose | map({ "start": (.[0] | strptime("%Y-%m-%dT%H:%M:%S.%f%z") | strftime("%Y-%m-%dT%H:%M:%SZ")), "end": (.[0] | strptime("%Y-%m-%dT%H:%M:%S.%f%z") | mktime + 3600 | strftime("%Y-%m-%dT%H:%M:%SZ")), "value": .[1] }) | tostring'

The plugin must return a JSON structure containing a list of time periods and prices. Date fields must be in the form YYYY-MM-DDTHH:MM:SSZ and the price in the correct currency unit (e.g. EUR). evcc works internally with 15-minute intervals; plugins may return hourly data, which is converted automatically.

[
{
"start": "2025-01-01T00:00:00Z",
"end": "2025-01-01T00:15:00Z",
"value": 25.0
},
{
"start": "2025-01-01T00:15:00Z",
"end": "2025-01-01T00:30:00Z",
"value": 26.5
},
{
"start": "2025-01-01T00:30:00Z",
"end": "2025-01-01T00:45:00Z",
"value": 24.8
},
{
"start": "2025-01-01T00:45:00Z",
"end": "2025-01-01T01:00:00Z",
"value": 27.2
}
]

The formula field accepts a Go expression with price, charges, tax and the slot timestamp ts in scope. The math library and time.Time methods on ts are available. The formula runs for the current price and each forecast slot.

Price cap:

charges: 0.22
tax: 0.19
formula: math.Min(0.5, (price + charges) * (1 + tax))

Caps the result at 50 ct/kWh.

No feed-in tariff on negative day-ahead prices (German PV systems commissioned after February 25, 2025):

formula: factor := 1.0; if price < 0 { factor = 0.0 }; factor * 0.07

Pays a fixed feed-in tariff of 7 ct/kWh, except when the day-ahead market price is negative.