From e10b95f4431201c6e1e3429013a8e3c09cde4681 Mon Sep 17 00:00:00 2001 From: Michael Geers Date: Sun, 14 Jun 2026 00:16:52 +0200 Subject: [PATCH] Templates: add caveats field for known device issues (#30641) --- AGENTS.md | 1 + templates/README.md | 24 +++++++++++++++++++ templates/definition/charger/alfen.yaml | 4 ++++ .../definition/charger/amperfied-solar.yaml | 4 ++++ templates/definition/charger/easee.yaml | 9 +++++++ .../charger/elli-charger-connect.yaml | 5 ++++ .../definition/charger/elli-charger-pro.yaml | 5 ++++ .../definition/charger/ocpp-wallbox-fw5.yaml | 9 +++++++ .../definition/charger/ocpp-wallbox.yaml | 9 +++++++ templates/definition/charger/vestel.yaml | 5 ++++ templates/definition/common-schema.json | 20 ++++++++++++++++ templates/definition/devices-schema.json | 3 +++ templates/definition/meter/shelly-3em.yaml | 8 ++++--- .../definition/meter/shelly-pro-3em.yaml | 8 ++++--- .../definition/meter/sungrow-hybrid.yaml | 5 ++++ util/templates/documentation.go | 7 ++++++ util/templates/documentation.tpl | 10 ++++++++ util/templates/template.go | 1 + util/templates/types.go | 19 +++++++++++++++ 19 files changed, 150 insertions(+), 6 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e78c50b56..87f445b5b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -91,6 +91,7 @@ Deep documentation on specific subsystems is available in `docs/agents/`. Load w - No em dashes (—) in comments, commit messages, or docs. Use periods, commas, or colons - Project name is `evcc`, always lowercase - Acronyms uppercase in prose: OCPP, MQTT, HEMS, SoC +- Terminology: German "Phasensaldierung" (meter netting signed power across phases each instant) is "summative energy measurement" in English. Avoid "phase balancing" (means load balancing) and "net metering" (a billing scheme) - Commit subjects: `Component: short description`, no trailing period. Sub-scope in parens: `Meter (Home Assistant): ...`. Use `chore:`/`fix:`/`docs:` only for non-feature changes ## Comment Style diff --git a/templates/README.md b/templates/README.md index 6a27b14bf..3227a4ce0 100644 --- a/templates/README.md +++ b/templates/README.md @@ -101,6 +101,30 @@ en: | **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`. + +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 `link` to 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 `description` follows the same Markdown formatting rules as `requirements.description` above. + +Example: + +```yaml +caveats: + - description: + de: Phasenumschaltung deaktiviert sich gelegentlich von selbst. + en: Phase switching occasionally disables itself. + link: https://github.com/evcc-io/evcc/issues/21708 +``` + ## `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. diff --git a/templates/definition/charger/alfen.yaml b/templates/definition/charger/alfen.yaml index acbc7f952..ed4e356dc 100644 --- a/templates/definition/charger/alfen.yaml +++ b/templates/definition/charger/alfen.yaml @@ -9,6 +9,10 @@ requirements: de: Die "Active load balancing" Lizenz wird benötigt um die Wallbox via Modbus extern zu steuern. In den Einstellungen muss "Active Load Balancing" aktiviert und "Energy Management System" als Data Source ausgewählt werden. Es wird empfohlen "ValidityTime" (Menu "TCP/IP EMS") auf 300s einzustellen. Falls die "Double"-Box verwendet wird müssen beide Ladepunkte getrennt voneinander hinzugefügt werden. Der erste Port (oder einzelne Port) ist unter ID 1 zugänglich, der zweite unter ID 2. en: The "Active load balancing" license is required for external Modbus control of the charger. Enable "Active Load Balancing" and select "Energy Management System" as Data Source in the configuration. It is recommended to set "ValidityTime" ("TCP/IP EMS" menu) to 300s. When using "Double" charger both loadpoints need to be added. The the first port (or single) is accessable on ID 1, second port on ID 2. evcc: ["sponsorship"] +caveats: + - description: + de: Phasenumschaltung synchronisiert sich nicht immer zuverlässig. + en: Phase switching does not always synchronise reliably. params: - name: modbus choice: ["tcpip"] diff --git a/templates/definition/charger/amperfied-solar.yaml b/templates/definition/charger/amperfied-solar.yaml index 56f9f9394..6732d0cde 100644 --- a/templates/definition/charger/amperfied-solar.yaml +++ b/templates/definition/charger/amperfied-solar.yaml @@ -6,6 +6,10 @@ products: capabilities: ["mA", "rfid", "1p3p", "meter", "dim"] requirements: evcc: ["sponsorship"] +caveats: + - description: + de: Automatische Phasenumschaltung (1P/3P) ist unzuverlässig und kann fehlschlagen. + en: Automatic phase switching (1P/3P) is unreliable and may fail. params: - name: modbus choice: ["tcpip"] diff --git a/templates/definition/charger/easee.yaml b/templates/definition/charger/easee.yaml index 474d1ad46..d5fa24684 100644 --- a/templates/definition/charger/easee.yaml +++ b/templates/definition/charger/easee.yaml @@ -15,6 +15,15 @@ products: capabilities: ["rfid", "1p3p", "meter", "dim"] requirements: evcc: ["sponsorship"] +caveats: + - description: + de: Seltene Energie-Updates können Ladehistorie und Sitzungsstatistik verfälschen. + en: Infrequent energy updates can distort charging history and session statistics. + link: https://github.com/evcc-io/evcc/issues/20594 + - description: + de: Bei mehreren Ladepunkten in einem Easee-Circuit wirkt die Phasenumschaltung auf alle Ladepunkte. + en: With multiple chargers in one Easee circuit, phase switching affects all of them. + link: https://github.com/evcc-io/evcc/issues/28859 params: - name: user required: true diff --git a/templates/definition/charger/elli-charger-connect.yaml b/templates/definition/charger/elli-charger-connect.yaml index edf059378..5e32a7738 100644 --- a/templates/definition/charger/elli-charger-connect.yaml +++ b/templates/definition/charger/elli-charger-connect.yaml @@ -34,6 +34,11 @@ requirements: Important: A mostly flawless functionality can only be provided with an external energy meter and no usage of CT coils, due to sosftware bugs of the Wallbox. Using a LAN connection is highly recommended. Note: If you've added an energy meter to your charger please use the Pro or Connected+ integration. +caveats: + - description: + de: "Viele bekannte EEBUS-Firmware-Fehler, die der Hersteller nicht behebt: Ladewerte fehlen oft oder sind veraltet und die Verbindung bricht häufig ab. Ein externer Zähler ist erforderlich." + en: "Many known EEBUS firmware bugs that the manufacturer will not fix: charging measurements are often missing or stale and the connection drops frequently. An external meter is required." + link: https://github.com/evcc-io/evcc/discussions/15367 params: - preset: eebus - name: ip diff --git a/templates/definition/charger/elli-charger-pro.yaml b/templates/definition/charger/elli-charger-pro.yaml index 79b2f5943..96953e89f 100644 --- a/templates/definition/charger/elli-charger-pro.yaml +++ b/templates/definition/charger/elli-charger-pro.yaml @@ -30,6 +30,11 @@ requirements: The identification of a vehicle using the RFID card is not possible. Important: A mostly flawless functionality can only be provided with an external energy meter and no usage of CT coils, due to sosftware bugs of the Wallbox. Using a LAN connection is highly recommended. +caveats: + - description: + de: "Viele bekannte EEBUS-Firmware-Fehler, die der Hersteller nicht behebt: Ladewerte können unzuverlässig sein und die Verbindung bricht häufig ab. Ein externer Zähler ist erforderlich." + en: "Many known EEBUS firmware bugs that the manufacturer will not fix: charging measurements can be unreliable and the connection drops frequently. An external meter is required." + link: https://github.com/evcc-io/evcc/discussions/15367 params: - preset: eebus - name: ip diff --git a/templates/definition/charger/ocpp-wallbox-fw5.yaml b/templates/definition/charger/ocpp-wallbox-fw5.yaml index 03f39be7c..f3918f2b2 100644 --- a/templates/definition/charger/ocpp-wallbox-fw5.yaml +++ b/templates/definition/charger/ocpp-wallbox-fw5.yaml @@ -33,6 +33,15 @@ requirements: * Charge Point Identity: Custom value (e.g. serial number of charger) which is reused in configuration as *stationid* * Password: leave empty evcc: ["sponsorship", "skiptest"] +caveats: + - description: + de: OCPP-Messwerte können fehlen oder unvollständig sein. + en: OCPP meter values can be missing or incomplete. + link: https://github.com/evcc-io/evcc/discussions/26186 + - description: + de: Die OCPP-Verbindung kann instabil sein und sich teils erst nach Neustart von evcc erholen. + en: The OCPP connection can be unstable and may only recover after restarting evcc. + link: https://github.com/evcc-io/evcc/issues/27203 params: - preset: ocpp - name: metervalues diff --git a/templates/definition/charger/ocpp-wallbox.yaml b/templates/definition/charger/ocpp-wallbox.yaml index 192fe7f70..5a05eb08a 100644 --- a/templates/definition/charger/ocpp-wallbox.yaml +++ b/templates/definition/charger/ocpp-wallbox.yaml @@ -33,6 +33,15 @@ requirements: * Charge Point Identity: Custom value (e.g. serial number of charger) which is reused in configuration as *stationid* * Password: leave empty evcc: ["sponsorship", "skiptest"] +caveats: + - description: + de: OCPP-Messwerte können fehlen oder unvollständig sein. + en: OCPP meter values can be missing or incomplete. + link: https://github.com/evcc-io/evcc/discussions/26186 + - description: + de: Die OCPP-Verbindung kann instabil sein und sich teils erst nach Neustart von evcc erholen. + en: The OCPP connection can be unstable and may only recover after restarting evcc. + link: https://github.com/evcc-io/evcc/issues/27203 params: - preset: ocpp render: | diff --git a/templates/definition/charger/vestel.yaml b/templates/definition/charger/vestel.yaml index 3d104e65d..26a504ce9 100644 --- a/templates/definition/charger/vestel.yaml +++ b/templates/definition/charger/vestel.yaml @@ -22,6 +22,11 @@ requirements: de: 1P3P erfordert Firmware 3.187.0 oder neuer, RFID erfordert 3.156.0 oder neuer. en: 1P3P requires at least firmware version 3.187.0, RFID at least 3.156.0. evcc: ["sponsorship"] +caveats: + - description: + de: Phasenumschaltung deaktiviert sich gelegentlich von selbst. + en: Phase switching occasionally disables itself. + link: https://github.com/evcc-io/evcc/issues/21708 params: - name: modbus choice: ["tcpip"] diff --git a/templates/definition/common-schema.json b/templates/definition/common-schema.json index 0e8c41a1d..7e6115a8c 100644 --- a/templates/definition/common-schema.json +++ b/templates/definition/common-schema.json @@ -68,6 +68,26 @@ ], "title": "Requirements" }, + "Caveats": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "description": { + "$ref": "#/definitions/LanguageText" + }, + "link": { + "type": "string", + "format": "uri" + } + }, + "required": [ + "description" + ] + }, + "title": "Caveats" + }, "ParamDevice": { "anyOf": [ { diff --git a/templates/definition/devices-schema.json b/templates/definition/devices-schema.json index 9f0f42d0e..0db5dd34e 100644 --- a/templates/definition/devices-schema.json +++ b/templates/definition/devices-schema.json @@ -47,6 +47,9 @@ "requirements": { "$ref": "common-schema.json#/definitions/Requirements" }, + "caveats": { + "$ref": "common-schema.json#/definitions/Caveats" + }, "params": { "type": "array", "items": { diff --git a/templates/definition/meter/shelly-3em.yaml b/templates/definition/meter/shelly-3em.yaml index c8fa69b30..a8aad136a 100644 --- a/templates/definition/meter/shelly-3em.yaml +++ b/templates/definition/meter/shelly-3em.yaml @@ -3,9 +3,11 @@ products: - brand: Shelly description: generic: 3EM (Gen.1) -# 3-phase Shelly EM devices count each phase's energy separately (non-balanced), -# so the totals are unsuitable for bidirectional grid metering. Energy and -# returnEnergy are therefore omitted for grid usage (see #29727). +caveats: + - description: + de: Integrierter Zähler ohne Phasensaldierung; stattdessen Leistungsintegration. + en: Built-in meter lacks summative energy measurement; power is integrated instead. + link: https://github.com/evcc-io/evcc/issues/29727 params: - name: usage choice: ["grid", "pv", "charge"] diff --git a/templates/definition/meter/shelly-pro-3em.yaml b/templates/definition/meter/shelly-pro-3em.yaml index c8a28556d..20d31da5f 100644 --- a/templates/definition/meter/shelly-pro-3em.yaml +++ b/templates/definition/meter/shelly-pro-3em.yaml @@ -2,9 +2,11 @@ template: shelly-pro-3em products: - { brand: Shelly, description: { generic: Pro 3 EM } } - { brand: Shelly, description: { generic: 3 EM-63T/W Gen3 } } -# 3-phase Shelly EM devices count each phase's energy separately (non-balanced), -# so the totals are unsuitable for bidirectional grid metering. The shelly meter -# suppresses energy and returnEnergy for grid usage (see #29727). +caveats: + - description: + de: Integrierter Zähler ohne Phasensaldierung; stattdessen Leistungsintegration. + en: Built-in meter lacks summative energy measurement; power is integrated instead. + link: https://github.com/evcc-io/evcc/issues/29727 params: - name: usage choice: ["grid", "pv", "charge"] diff --git a/templates/definition/meter/sungrow-hybrid.yaml b/templates/definition/meter/sungrow-hybrid.yaml index 235f1e0ea..87637c6ca 100644 --- a/templates/definition/meter/sungrow-hybrid.yaml +++ b/templates/definition/meter/sungrow-hybrid.yaml @@ -9,6 +9,11 @@ requirements: description: de: Verbindungen über das WiNet-S-Dongle (WiFi oder LAN) funktionieren nur mit aktueller Firmware. Ältere Versionen liefern nicht alle benötigten Daten (Leistung, Ladestand). en: Connections via the WiNet-S dongle (WiFi or LAN) only work with the latest firmware. Older versions do not provide all required data (power, state of charge). +caveats: + - description: + de: Für korrekte Funktion dürfen maximale Lade- und Entladeleistung nicht zu hoch angesetzt werden. + en: For correct operation, maximum charge and discharge power must not be set too high. + link: https://github.com/evcc-io/evcc/discussions/23557 params: - name: usage choice: ["grid", "pv", "battery"] diff --git a/util/templates/documentation.go b/util/templates/documentation.go index 04c2a73b9..72990a076 100644 --- a/util/templates/documentation.go +++ b/util/templates/documentation.go @@ -89,6 +89,12 @@ func (t *Template) RenderDocumentation(product Product, lang string) ([]byte, er return 0 }) + type caveatDoc struct{ Description, Link string } + var caveats []caveatDoc + for _, c := range t.Caveats { + caveats = append(caveats, caveatDoc{c.Description.String(lang), c.Link}) + } + data := map[string]any{ "Template": t.Template, "ProductIdentifier": product.Identifier(), @@ -99,6 +105,7 @@ func (t *Template) RenderDocumentation(product Product, lang string) ([]byte, er "Countries": t.Countries, "Requirements": t.Requirements.EVCC, "RequirementDescription": t.Requirements.Description.String(lang), + "Caveats": caveats, "Params": filteredParams, "AdvancedParams": hasAdvancedParams, "Usages": t.Usages(), diff --git a/util/templates/documentation.tpl b/util/templates/documentation.tpl index 7324807e9..fd6d1c953 100644 --- a/util/templates/documentation.tpl +++ b/util/templates/documentation.tpl @@ -77,6 +77,16 @@ requirements: ["{{ join "\", \"" .Requirements }}"] description: | {{ .RequirementDescription | indent 2 }} {{- end }} +{{- if .Caveats }} +caveats: +{{- range .Caveats }} + - description: | +{{ .Description | indent 6 }} +{{- if .Link }} + link: {{ .Link }} +{{- end }} +{{- end }} +{{- end }} render: {{- if .Usages -}} {{- $content := . }} diff --git a/util/templates/template.go b/util/templates/template.go index 8f1bee737..a16c4084c 100644 --- a/util/templates/template.go +++ b/util/templates/template.go @@ -25,6 +25,7 @@ type Template struct { Capabilities []Capability `json:",omitempty"` Countries []CountryCode `json:",omitempty"` // list of countries supported by this template Requirements Requirements `json:",omitempty"` + Caveats []Caveat `json:",omitempty"` // known device limitations Params []Param `json:",omitempty"` Render string `json:"-"` // rendering template } diff --git a/util/templates/types.go b/util/templates/types.go index 6009ceafc..8ff5739d7 100644 --- a/util/templates/types.go +++ b/util/templates/types.go @@ -178,6 +178,25 @@ type Requirements struct { Description TextLanguage // Description of requirements, e.g. how the device needs to be prepared } +// Caveat documents a known device limitation +type Caveat struct { + Description TextLanguage // localized description of the limitation + Link string `json:",omitempty"` // optional URL with more details +} + +func (c Caveat) MarshalJSON() ([]byte, error) { + mu.Lock() + custom := struct { + Description string `json:",omitempty"` + Link string `json:",omitempty"` + }{ + Description: c.Description.String(encoderLanguage), + Link: c.Link, + } + mu.Unlock() + return json.Marshal(custom) +} + // Param is a proxy template parameter // Params can be defined: // 1. in the template: uses entries in 4. for default properties and values, can be overwritten here