Lovelace-Custom-Card für Home Assistant zur Live-Visualisierung des Energieflusses in Mehr-Quellen-Haushalten — beliebig viele PV-Anlagen, Akkus (1:1 mit ihrer ladenden PV gepairt), Großverbraucher.
Standard: Verbraucher einzeln
Zwei PV-Anlagen (Dach + Balkon), zwei Akkus (Dach-Speicher + Balkon-Speicher mit SoC-Ring), Netz links, Hausverbrauch mittig, drei Verbraucher rechts (Wärmepumpe, Wallbox, Herd). Animierte Punktströme zeigen die aktiven Energieflüsse; der Ring um den Haus-Knoten visualisiert die Quellen-Anteile.
Optional: Gruppierung nach HA-Area
Mit display.consumer_grouping: by_area listest du Sensoren wie gewohnt
einzeln, die Card resolvt pro Sensor aber die HA-Area und merged sie
automatisch zu Gruppen-Knoten. Hier: 8 Smart-Plug-Sensoren werden in der
Anzeige zu 3 Räumen zusammengefasst — Büro (PC + Monitor), Küche
(Herd + Geschirrspüler + Mikrowelle), Wohnzimmer (TV + Soundbar + Licht).
- Solar oben, Netz links, Akkus unten, Verbraucher rechts, Haus mittig — alle Knoten als Kreise
- Animierte Punktströme entlang aktiver Pfade (Geschwindigkeit/Anzahl skaliert mit Leistung)
- Anteils-Ring um den Haus-Knoten zeigt Quellen-Anteile am aktuellen Verbrauch
- Werte in Watt mit Tausendertrennung; Netz mit Vorzeichen (
+Bezug/−Einspeisung) - HA-Theme-aware (Light/Dark folgt automatisch)
- Klick auf Knoten → HA-
more-info-Dialog - Tastatur-navigierbar
- YAML-Config plus grafischer Editor
- HACS-installierbar
- HACS öffnen → "Custom repositories" → Dieses Repo als "Lovelace" hinzufügen.
- "Custom Energy Flow Card" installieren.
- Resource in
configuration.yaml(oder UI) eintragen:resources: - url: /hacsfiles/custom-energy-flow-card/custom-energy-flow-card.js type: module
Siehe examples/2-pv-2-batt.yaml für eine
vollständige Beispiel-Konfiguration mit 2 PV-Anlagen, 2 Akkus, 3 Verbrauchern.
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
type |
custom:custom-energy-flow-card |
ja | — |
title |
string | nein | Card-Titel |
solar[] |
Liste | nein | siehe unten |
battery[] |
Liste | nein | siehe unten |
grid |
Objekt | ja | siehe unten |
home |
Objekt | nein | optionaler Override-Sensor |
consumers[] |
Liste | nein | siehe unten |
display |
Objekt | nein | Anzeige-Optionen |
- id: <eindeutig im solar-Array>
name: <optional>
power: sensor.<entity> # in W, kW, mW (auto-konvertiert)
icon: mdi:<icon> # optionalEntweder ein signierter Power-Sensor:
- id: <eindeutig im battery-Array>
name: <optional>
soc: sensor.<entity> # 0–100 %
power: sensor.<entity> # signiert: + laden, − entladen
power_invert: false # falls Sensor umgekehrt liefert
charged_by: <solar.id> # Pairing → Pflicht, 1:1
icon: mdi:<icon>oder zwei separate Sensoren (z. B. Sungrow, Solarwatt):
- id: <eindeutig im battery-Array>
name: <optional>
soc: sensor.<entity> # 0–100 %
charge_power: sensor.<entity> # ≥ 0, nur Lade-Leistung
discharge_power: sensor.<entity> # ≥ 0, nur Entlade-Leistung
charged_by: <solar.id> # Pairing → Pflicht, 1:1
icon: mdi:<icon>Genau eine der beiden Varianten pro Battery — nicht beides, nicht keines.
Entweder ein signierter Sensor:
grid:
power: sensor.grid_power # + Bezug, − Einspeisung
power_invert: falseoder zwei separate:
grid:
import: sensor.grid_import
export: sensor.grid_exporthome:
name: <optional Anzeigename> # Default: "Hausverbrauch"
power: sensor.<entity> # optional Override-Sensor (W)
icon: mdi:<icon>Ohne power wird der Hausverbrauch aus der Bilanz berechnet:
P_home = ΣPV + ΣAkku-Entladen + Netzbezug − ΣAkku-Laden − Einspeisung
- name: <Anzeigename> # required
power: sensor.<entity> # ≥ 0
icon: mdi:<icon>display:
active_threshold_w: 5 # darunter wird der Pfad ausgeblendet
number_format: grouped # "standard" | "grouped"
show_inactive_paths: false
animation:
base_duration_s: 2.5
reference_power_w: 1000
min_duration_s: 0.6
max_dots_per_path: 4
colors: # optional Override pro semantischer Rolle
solar: '#f59e0b' # Solar-Fluss
battery: '#10b981' # Akku → Haus
grid_import: '#6b7280' # Netzbezug
grid_export: '#16a34a' # Einspeisung
home: '#ef4444' # Haus-Knoten
consumer: '#db2777' # Verbraucher
warning: '#eab308' # Diagnose-Icon (Engine-Warnings)Optional. Default: none.
none(Default) — jeder Sensor ausconsumers[]wird als eigener Knoten gezeigt.by_area— die Card resolvt für jeden Sensor die zugewiesene Area (aus HAs Entity/Device-Registry) und merged Sensoren gleicher Area zu einer Gruppe. Anzeige-Name = Area-Name.
Beispiel: siehe examples/with-grouping.yaml.
Hinweise zur Visualisierung:
- Optimiert für 1–6 PV-Anlagen und 1–8 sichtbare Verbraucher (Einzel-Sensoren oder Area-Gruppen).
- Bei > 8 Verbrauchern wird der Bogen visuell dicht — funktional bleibt alles erhalten, aber die Lesbarkeit leidet.
- Sensoren ohne Area landen in einer Gruppe „Sonstige".
Alle power/soc-Felder erwarten die HA-Standard-Form domain.object_id
(Regex: ^[a-z_][a-z0-9_]*\.[a-z0-9_]+$). Beispiel: sensor.solar_dach_power ✓,
not_an_entity ✗.
Power-Sensoren werden mit unit_of_measurement aus den HA-Attributen erkannt
und automatisch nach W konvertiert (W, kW, mW, VA unterstützt).
Falls die Card nicht wie erwartet funktioniert: setze display.debug: true in
der Config. Die Card schreibt dann ausführliche [CEFC] …-Logs in die
Browser-Console (HA-Frontend → DevTools → Console), die uns bei Bug-Triage helfen.
display:
debug: trueJeder Akku referenziert genau eine PV via charged_by. Eine PV darf
höchstens einer Battery zugeordnet sein (1:1). Eine PV ohne gepairten
Akku ist erlaubt; ein Akku ohne charged_by ist nicht erlaubt.
- PV-Sensor: ≥ 0 W
- Akku-Sensor: entweder signiert (
+= laden,−= entladen;power_invert: truefalls Sensor umgekehrt arbeitet) oder zwei separate ≥ 0-Sensoren (charge_power+discharge_power) - Netz-Sensor: signiert:
+= Bezug,−= Einspeisung. Oder alternativ zwei separate Sensorenimport/export
Die Card stellt CSS ::part()-Hooks bereit:
| Part | Element |
|---|---|
card |
Card-Wrapper |
node |
jeder Knoten |
node-solar / node-battery / node-grid / node-home / node-consumer |
per Typ |
flow |
jeder Fluss |
flow-pv-to-home / … |
per Pfad-Typ |
home-ring |
Anteils-Ring |
- Card und Editor folgen jetzt der Home-Assistant-Sprache (
hass.locale.language). de(inkl.de-DE,de-AT,de-CH) → deutsche Texte wie bisher.- Alle anderen Sprachen → englische Texte.
- Kein Config-Eintrag nötig — wechselt automatisch beim HA-Sprachwechsel.
User mit einer Home-Assistant-Sprache ≠ de sehen die Card ab v0.14.0 auf
Englisch (vorher Deutsch). Wer beim alten Verhalten bleiben möchte, kann
in den HA-Profil-Einstellungen die Sprache auf Deutsch stellen.
- Browser-Cache leeren (Strg+Shift+R), falls die alte Sprache noch erscheint.
- Keine Config-Anpassung nötig.
Neues User-facing Feature am Akku-Knoten:
- SoC-Prozentwert direkt im Akku-Ring sichtbar (z. B. „73 %") — tangential oben-links im Stroke. Bisher war der Ladestand nur als Ring-Füllung dargestellt, jetzt steht der genaue Wert daneben.
- Akku-Ring breiter (Stroke-Width 6 → 14 px), um den Prozent-Text aufzunehmen. Akku-Kreis-Radius (r=42) und Ring-Radius (r=50) bleiben gleich — Layout- Verhalten unverändert.
- Theme-adaptive Schriftfarbe für den %-Text: dunkel im Light-Theme, hell im
Dark-Theme (via
--primary-text-color). Bestehendecard-mod-Selektoren bleiben kompatibel. - Akku-Name-Label sitzt 8 px weiter unten, damit Name und Ring sich nicht berühren.
- aria-Label-Format auf
"X %"mit Leerzeichen angepasst (konsistent zum Watt-Format"X.Y kW").
Interne Architektur-Änderungen:
- Bundle-Budget angehoben von 60 KiB auf 64 KiB (ADR-0022). Hintergrund: Whitespace-Optimierung in Lit-Templates war erschöpft, neue Render-Features hatten keinen Headroom mehr ohne Lesbarkeits-Verlust. CI-Gate weiter aktiv, nur Schwellenwert verschoben.
Card-Mod-Hinweis: Der Shadow-DOM-Part ::part(battery-ring) zielt jetzt auf
den äußeren <g>-Wrapper (vorher: innere Rotationsgruppe). Neuer Hook:
::part(battery-ring-label) für den %-Text. Bestehende Selektoren, die nur den
Ring-Stroke stylen, sollten weiter funktionieren — Custom-CSS, das auf die
innere Gruppen-Struktur baute, ist evtl. anzupassen.
Keine Config-Migration nötig. SoC-Sensor war seit v0.9.0 Pflicht-Feld der Battery-Config — Anzeige aktiviert sich automatisch, sobald der Sensor verfügbar ist.
Visuelles Polish-Release. Behebt vier Render-Issues aus dem Live-Betrieb:
- Icon-Positionierung in den Knoten-Kreisen vergrößert (~10 px Spacing zwischen Icon und Wert)
- PV/Batterie/Grid-Kreise vergrößert für 4–5-stellige Werte (z. B.
−12.345 W) - Consumer-Icon vergrößert (18 → 24 px)
- Battery-Ring sitzt jetzt außerhalb des Batterie-Kreises
- Default-Icon für Batterie:
mdi:battery→mdi:home-battery - Grid-Wert-Font auf 13 px (statt 14 wie bei PV/Batt) — gibt der kleinsten Kreis-Geometrie (r=40)
zusätzlichen Headroom für 5-stellige Werte mit Vorzeichen (
−12.345 W).
Keine Config-Migration nötig. Bestehende User-Configs mit eigenem icon:-Property
bleiben unverändert.
- MDI-Icons werden ab v0.12.0 gerendert. Konfigurierte
icon: mdi:*-Werte in Solar/Battery/Verbraucher zeigen jetzt das gewählte Icon (vorher nur Default-Emojis). Area-Icons aus HA werden imconsumer_grouping: 'by_area'- Mode automatisch verwendet. - Diagnose-Icon (gelber Badge top-right bei Engine-Warnings) zeigt jetzt
mdi:alert-circle-outlinestatt!.
- Editor-Feldreihenfolge:
idist nicht mehr editierbar (wird auto- generiert). Solar- und Battery-Einträge zeigen jetzt zuerstName, dann Sensor-Felder, dannIcon. Für User mit Muskelgedächtnis merklich, aber besser (Name first). - Pairing-Dropdown (welche PV lädt diesen Akku?) zeigt
Solar pv1stattpv1bei unbenannten PV-Anlagen — konsistent mit der Card-Anzeige. - Visuelle Diff: Knoten-Icons werden jetzt in der Knoten-Farbe gerendert
(Solar-Gelb, Battery-Grün usw.) statt monochrom. Optionaler card-mod-Hook
via
::part(node-icon).
- Neuer ADR-0020 dokumentiert die Strategie-Wahl (ha-icon via foreignObject statt inline mdi-paths).
Breaking visual change. Existierende Configs funktionieren unverändert, aber die Optik der Card ist neu:
- ViewBox 720×540 → 820×540 (breiter wegen Verbraucher-Labels rechts neben den Knoten).
- PVs und Akkus clustern in der linken 2/3-Fläche (x ∈ [130, 440]) statt voll verteilt.
- Verbraucher sind ein Bogen rechts um Home (statt vertikale Spalte).
- Akku-Ladestand als Ring statt Text-Label (analog zum Home-Attribution-Ring).
Neu:
display.consumer_grouping: by_area— automatische Verbraucher-Gruppierung nach HA-Area (sieheexamples/with-grouping.yaml).- SoC-Sensor wird im Akku-Knoten als gefüllter Ring visualisiert (0–100 %).
Falls das alte Aussehen explizit benötigt wird: GitHub-Issue eröffnen —
display.layout: 'classic' ist als v1.x-Option vorgesehen.
- ViewBox-Aspect 16:9 (statt ~1.52:1): Die Card nutzt jetzt die Dashboard-Breite besser. Funktionalität und Daten unverändert — Sensoren, Edges, Animation, Theme sind identisch zu 0.10.x.
- HA-Layout-API entfernt: Die Card deklariert keine
getGridOptionsmehr → HA's Layout-Editor erlaubt freie Skalierung ohne künstliche Slider-Obergrenze.
- Browser-Cache leeren (Strg+Shift+R / Cmd+Shift+R), falls die alte Optik noch erscheint
- Falls der Default-Slot nach Update zu klein wirkt: HA-Dashboard → "Card bearbeiten" → "Layout" → Größe manuell anpassen
- Optimaler HA-Sections-Slot: 12×9 oder 12×10
MIT.

