Templates folder documentation
Folders
- definition: hold all device templates definitions in yaml files
- charger: all charger templates
- meter: all meter templates
- vehicle: all vehicle templates
- docs: content is generated via
go generate ./...using the above templates for the evcc documentation page to be used
Template Documentation
The following describes each possible element in a yaml file
`template`
template expects a unique template name for the current device class (charger, meter, vehicle are device classes)
`products`
products expects a list of products that work with this template.
Each product contains:
brand: company that makes the product or offers the service. No regions, variants, or API names โ those, if required for clarity, belong indescription.description: product, service, model, or API name. Expectsgeneric,de,en.
Either brand or description needs to be set. Examples by device class:
- Vehicles โ
brandis the make,descriptionthe connected service:brand: Hyundai,description.generic: Bluelinkbrand: Hyundai,description.generic: Bluelink (US)
- Chargers โ
brandis the manufacturer,descriptionthe product model:brand: ABL,description.generic: eMH1brand: ABL,description.generic: eMH2brand: Alfen,description.generic: Eve
- Meters โ
brandis the manufacturer,descriptionthe product model:brand: ABB,description.generic: A43brand: my-PV,description.generic: AC ELWA 2
- Tariffs โ
brandis the service provider,descriptionthe API variant:brand: Electricity Maps,description.generic: Commercial APIbrand: Electricity Maps,description.generic: Free API
- Generic integrations (OSS tools, community projects): omit
brand, put the project name indescription.generic, setgroup: generic. Keep upstream casing (e.g.TeslaFi,ioBroker.bmw,mg2mqtt).
Note: The official website of the manufacturer or service provider is the reference for the exact spelling.
`link`
link is an optional URL pointing to the integration provider. It is shown during configuration and in the documentation.
Guidelines:
- The URL must start with
https://. - Only add a link if it is useful for configuring the device, e.g. the cloud portal where credentials or tokens are managed, the page of the connected service, or the project page of a generic integration.
- Link the page that describes the actual service being integrated, e.g. the dynamic tariff product page or the dataset page, not the company homepage. The homepage is fine when the whole site is that single service.
- Write for end users: the page should describe the service and ideally offer a signup or account/token call to action. Do not link API documentation or developer portals.
- Do not link general product detail or marketing pages, e.g. the manufacturer page of a charger.
- Use canonical, stable URLs in the provider's default language and without tracking parameters. Verify that the URL is live.
linkcan be set at the template level (applies to all products) and overridden per product via alinkentry underproducts.
Example (template-level link, overridden by a rebranded product):
template: smartcharge
link: https://portal.smartcharge.example.com
products:
- ...
- brand: PowerCloud
link: https://portal.powercloud.example.com`group`
group is used to group switchable sockets and generic device support (e.g. SunSpec) templates.
`capabilities`
capabilities provides an option to define special capabilities of the device as a list of strings.
Possible values:
iso151182: The device supports communicating via ISO 15118-2.mA: The device supports granular (milliamp) current control.rfid: The device supports RFID.1p3p: The device supports 1P/3P phase switching.battery-control: The device supports battery control.meter: The device has a built-in energy meter.dim: The device supports EnWG ยง14a dimming.curtail: The device supports EEG ยง9 curtailment.
capabilities can be set at two levels:
- Template level (next to
template): applies to every product. - Product level (under a
productsentry): applies to that product only.
Both levels are merged, not overwritten: template-level capabilities are appended to each product's own list. A product cannot remove an inherited capability, and duplicates are rejected, so do not repeat a template-level capability on a product.
Example (all products get 1p3p; only the second product additionally gets meter):
template: demo-charger
capabilities: ["1p3p"]
products:
- brand: Demo
description:
generic: Basic
- brand: Demo
description:
generic: Plus
capabilities: ["meter"] # effective: ["meter", "1p3p"]`requirements`
requirements provides an option to define various requirements / dependencies that need to be setup
`evcc`
evcc is a list of evcc specific system requirements
Possible Values:
sponsorship: If the device requires a sponsorship tokeneebus: If the device is accessed via the EEBus protocol and thus requires the corresponding setupmqtt: If the device a MQTT setup
`description`
description expects language-specific texts via de, en to provide specific things the user has to do, e.g. minimum firmware versions or specific hardware setup requirements.
Markdown formatting:
- The content can be multiline
- The content supports Markdown formatting
- External URLs should always use Markdown link format with the hostname as display text:
[docs.example.com](https://docs.example.com/path/to/page). This provides clear context while keeping the text readable. - Omit
www.from the display text:[example.com](https://www.example.com/path) - GitHub URLs use
github.com/user/repoas display text:[github.com/user/repo](https://github.com/user/repo) - Use code formatting
`text`for technical identifiers, tokens, configuration values, and entity patterns - Placeholder and example URLs (IP addresses, hostnames, device endpoints) should also use code formatting:
`http://<charger-host>:8000/semp`,`ws://<evcc-host>:8887/` - Use angle-bracket placeholders for device addresses:
<evcc-host>,<charger-host>,<meter-host>, `` - Use only plain ASCII quotes (
โ,โ) โ never typographic/curly quotes (โ,โ,โ,โ,โ) - Use bold formatting
**text**sparingly and only for important warnings or critical information
Example:
en: |
Requires `hcaptcha` token from [developer.example.com](https://developer.example.com/tokens).
Configure the SEMP base URL (`http://<charger-host>:8000/semp`).
Set the backend URL to `ws://<evcc-host>:8887/`.
**Attention**: Token is only valid for 2 minutes.`caveats`
caveats documents known limitations or unreliable behaviour of a device that otherwise works. This is distinct from requirements.description, which covers setup steps the user must perform.
It is a list, so a device can have multiple caveats. Each entry has a language-specific description (de, en) and a link.
Like capabilities, caveats can be set at template level (applies to every product) or product level (under a products entry, applies to that product only). Template-level caveats are appended to each product's own list, so do not repeat a template-level caveat on a product.
Guidelines:
- Add one entry per distinct problem (e.g. "unreliable meter" and "occasional reboots" are two entries); don't list the same problem twice.
- Keep descriptions as concise as possible while still understandable.
- Use factual wording describing the observed behaviour.
- Always add a
linkto the single issue or discussion that best documents the problem, so the situation can be re-verified later. It is technically optional, but omitting it should be a rare exception. - The
descriptionfollows the same Markdown formatting rules asrequirements.descriptionabove.
Example:
caveats:
- description:
de: Phasenumschaltung deaktiviert sich gelegentlich von selbst.
en: Phase switching occasionally disables itself.
link: https://github.com/evcc-io/evcc/issues/21708Example (caveat for one product only):
template: demo-charger
products:
- brand: Demo
description:
generic: Basic
- brand: Demo
description:
generic: Plus
caveats:
- description:
de: Phasenumschaltung deaktiviert sich gelegentlich von selbst.
en: Phase switching occasionally disables itself.
link: https://github.com/evcc-io/evcc/issues/21708`discovery`
discovery describes how the devices of a template can be recognized in the local network. The host suggestions mark matching hosts and use them for auto-fill. Any single hit is a match.
discovery:
mdns: ["_shelly._tcp", "_http._tcp:shelly*"] # service type in the announced spelling, optional instance name pattern after the colon
hostname: ["shelly*"] # pattern for any DNS or mDNS name of the host, domain is ignored, case-insensitive
mac: ["8400EC"] # hardware address prefix, 6 to 9 upper case hex digitsGuidelines:
- Only add hints verified against the IEEE registry (
mac), the vendor's documentation, or a real device. A registered prefix does not guarantee that the devices use it, many products contain third-party network modules. - Hostname patterns must be specific to the vendor. Patterns like
hs*match unrelated devices. - ESP-based devices (Shelly, Tasmota, OpenDTU) share the Espressif prefixes. Use
mdnsorhostnamefor them. - The "Network discovery" modal on the config page (experimental) shows how configured devices appear in the network and is the source for new hints.
`auth`
auth defines OAuth authentication configuration for devices that require user authorization. When specified, the UI OAuth flow and token management are handled automatically. The auth endpoint is called when all required parameters are filled and is re-called on every parameter change.
`type`
type specifies the OAuth provider type. This must reference a dedicated OAuth implementation.
Available types: homeassistant, ford-connect, viessmann, cardata, volvo-connected
`params`
params is a list of parameter names (from the params section) that are required for the OAuth configuration. These parameters will be passed to the authentication provider when initiating the OAuth flow. Once all listed parameters have values, the authorization is prepared and the UI displays a redirect link to the external service and device code (if applicable). The preparation is re-triggered whenever any parameter value changes.
Example:
auth:
type: viessmann
params: [clientid, redirecturi, gateway_serial]`params`
params describes the set of parameters the user needs to provide a value for.
`preset`
preset reference value of a predefined params set defined in parambaselist.yaml, so these params don't need to be redefined in each template. The example and default values for each predefined value can be overwritten.
`name`
name expects a name for the parameter, which will be used in the render section to reference the param and provide the user entered value.
Note: There a few default name values with specific internal meaning and consequences!
Predefined name values:
usage: specifies a list of meter classes, the device can be used for. Possible values aregrid,pv,battery, andchargermodbus: specifies that this device is accessed via modbus. It requires thechoiceproperty to have a list of possible interface values the device provides. These values can bers485andtcpip. The command will use either to ask the appropriate questions and settings. Therendersection needs to include the string{{include "modbus" .}}in all places where the configuration needs modbus settings.
Modbus Options
id: Device specific default for modbus IDport: Device specific default for modbus TCPIP portbaudrate: Device specific default for modbus RS485 baudratecomset: Device specific default for modbus RS485 comset
`description`
description allows to define user friendly and language specific names via de, en, generic
`dependencies`
dependencies allows to define a list of checks, when this param should be presented to the user, if it should be only in special cases
`name`
name referenced the param name value
`check`
check defines which kind of check should be performed
Possible values:
empty: if thevalueof the referencedparamnameshould be emptynotempty: if thevalueof the referencedparamnameshould be NOT emptyequal: if thevalueof the referencedparamnameshould match the value of thevalueproperty
`value`
value property is used in the equal check
`required`
required: true defines if the user has to provide a value. Default is false
`mask`
mask: true defines if the user input should be masked in the UI (password field). Used for sensitive credentials like passwords, tokens, and API keys that should be hidden from view. Default is false.
Note: Cannot be used together with private.
`private`
private: true marks a parameter as containing personal data (e.g., email addresses, VIN numbers, MAC addresses, locations). This data will be redacted from bug reports and diagnostic information but is visible in the UI. Default is false.
Examples of private data: usernames, email addresses, VIN, URI, MAC addresses, latitude/longitude, serial numbers
Note: Cannot be used together with mask.
`default`
default defines a default value to be used, which will be pre-filled in the configuration UI.
`example`
example provides an example value, so the user can get an idea of what is expected and what to look out for
`type`
type allows to define the value type to let the UI verify the user provided content
Possible values:
string: for string values (default)bool: fortrueandfalsevalueschoice: for a selection from predefined options (defined inchoiceproperty)chargemodes: for a selection of charge modes (Off,Smart,Now), includingNonewhich results in the param not being setduration: for duration values (e.g.,5m,1h30m,10s)float: for floating point numbersint: for integer valueslist: for a list of strings (newline-separated in textarea), e.g., used for defining a list ofidentifiersfor vehicles
`choice`
choice defines the list of possible values when type: choice is used. The user can select one value from this list via a dropdown.
Format: Array of strings
Example:
- name: schema
type: choice
choice: ["https", "http"]
default: https
- name: channel
type: choice
choice: ["general", "feedIn", "controlledLoad"]
required: true`advanced`
advanced: true marks a parameter as advanced. Advanced parameters are hidden by default in the UI and can be expanded by the user. Mostly used for non-required params that are meant for users with advanced needs and knowledge.
`help`
help expects language specific help texts via generic (language independent), de, en
`service`
service specifies an API endpoint that provides dynamic data or suggestions for this parameter during configuration. When set, the UI will call this service to provide auto-completion or pre-populated options to the user.
Format: service-name/endpoint or service-name/endpoint?param1={param1}¶m2={param2}
Parameters from other params can be referenced using {param-name} syntax, which will be replaced with the user's input for that parameter. {template} is the name of the selected template. The endpoint is only called once all referenced required parameters have a value. Referenced optional parameters, e.g. user or password, are replaced with an empty string while empty, so the service must handle missing values. The endpoint is called every time a referenced parameter value changes.
Response formats:
Service endpoints return either an array of strings (e.g., ["value1", "value2"]) or an array of objects with context:
[
{
"value": "192.168.1.10",
"label": "inverter.local",
"hint": "SMA",
"match": true,
"used": false
}
]value: written to the field (required)label: secondary line below the valuehint: shown on the right, e.g. a brandmatch: the entry fits the current context, listed in a separate group on topused: the entry is already taken by another device, listed last
A service that is still collecting data answers with the Retry-After header (seconds). The UI shows a searching indicator and fetches again after that time.
UI behaviour:
Values are shown as suggestions, not strict selections - users can always enter custom text values. The UI handles service responses differently based on the parameter configuration and response content:
Auto-fill (prepopulation): If the service returns exactly one value (or exactly one unused
matchfor object responses), the parameter is required, and the field is currently empty, the value will be automatically filled into the field.Dropdown suggestions: In all other cases (multiple values, non-required parameter, or field already has a value), the returned values are shown as a datalist (strings) or a combobox with grouping (objects) for the user to select from or ignore.
Empty response: If the service returns an empty array or no data, the field remains a regular text input.
Available services:
Network
network/hosts?template={template}: Lists the hosts of the local network found by mDNS, SSDP and the neighbor table of the operating system, with hostname and vendor. Hosts matching the template'sdiscoveryhints are marked. Thehostparam uses it by default.EVCC_DISCOVERY_HOSTSreplaces the scan with a static list, e.g. where the network is not reachable:[{"ip": "192.168.1.10", "mac": "00:15:BB:12:34:56", "hostname": "sma3009876543"}]. An empty list[]disables discovery.Hardware
hardware/serial: Lists available serial ports on the systemModbus
modbus/read?...: Reads a value from a modbus register (for validation/testing)The
modbusservice supports a special{modbus}parameter that will be automatically expanded to the appropriate connection parameters based on the user's modbus configuration:yaml# Template definition - name: voltage service: modbus/read?address=100&type=holding&{modbus} # Expanded for TCP connection: # modbus/read?address=100&type=holding&uri=192.168.1.10:502&id=1 # Expanded for RTU connection: # modbus/read?address=100&type=holding&device=/dev/ttyUSB0&baudrate=9600&id=1Home Assistant
homeassistant/instances: Auto-discovers Home Assistant instances on the networkhomeassistant/entities?uri={uri}&domain=sensor: Lists entities from a Home Assistant instance filtered by domain(s). Multiple domains can be comma-separated (e.g.,domain=sensor,binary_sensorordomain=number,input_number)
`render`
render contains the internal device configuration. All param name values can be used as a template variable, e.g. {{ .host }} for a param named host. The content is a go template, so all of go template feature can be used, e.g. {{- if ... }} statements, etc.
render is evaluated once when the device is configured. Plugin fields like the HTTP uri and body are go templates themselves and are evaluated on every request (sprig functions plus addDate and timeRound). Time-dependent expressions must be deferred to request time by wrapping them in a raw string, otherwise now freezes at config time:
uri: https://example.org/forecast?from={{ `{{ now | date "2006-01-02" }}` }}&to={{ `{{ addDate now 0 0 5 | date "2006-01-02" }}` }}