Im SmartHome ist die Visualisierung der aktuellen Zustände ein entscheidender Baustein: Wer weiß, ob Fenster offen sind, welche Temperatur in den Räumen herrscht oder wie viel Strom gerade verbraucht wird, kann effizienter steuern und Energie sparen. In diesem Artikel zeige ich dir, wie mit wenig Aufwand ein vollkommen individuelles Widget entsteht, um Messwerte und Zustände darzustellen.
Ablauf
Anfang und Ende liegt bei einem Web Image Widget (App) auf dem Smartphone. Es setzt den Request an den Node-RED HTTP-Endpunkt ab. Node-RED füllt ein beliebiges SVG-Template mit Werten und speichert dieses temporär ab. Die SVG wird in eine PNG umgewandelt und an das Web-Image-Widget ausgeliefert.
Auf einem Raspi 4 klappt das innerhalb von gut 200ms.
Schritt 1: HTTP-Endpunkt /render
Der Flow beginnt mit einem http in
-Node, der auf GET-Anfragen an /render
wartet.
{
"type": "http in",
"url": "/render",
"method": "get"
}

Schritt 2: SVG mit den aktuellen Werten erzeugen
Der zentrale Baustein ist das Function
Node, welches das vorbereitete SVG-Icon mit Live-Daten befüllt, bei mir hauptsächlich aus globalen Variablen. Der Kreativität und auch Dynamik sind hier keine Grenzen gesetzt. Eine Rundungsfunktion hab ich auch mit drin, damit die Zahlen nicht aus dem Layout laufen.
// Beispielhafte globale Variablen (im Flow vorher setzen!)
var temp_out = global.get("temp_out") || 'n/a';
var temp_wohnzimmer = global.get("temp_wohnzimmer") || 'n/a';
var temp_schlafzimmer = global.get("temp_schlafzimmer") || 'n/a';
var verbrauch = global.get("verbrauch_aktuell") || 'n/a';
function r(v) {
return (typeof v === "number") ? Math.round(v * 10) / 10 : "-";
}
// SVG erzeugen
msg.payload = `
<svg version="1.1" viewBox="0 0 300 200" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="#222"/>
<text x="10" y="30" fill="#fff" font-family="DejaVu Sans" font-size="20">🏠 SmartHome Status</text>
<g font-size="16">
<text x="10" y="70" font-family="Noto Color Emoji">🌡️</text>
<text x="40" y="70" fill="#fff" font-family="DejaVu Sans">Außen: ${r(temp_out)}°C</text>
<text x="10" y="100" font-family="Noto Color Emoji">🛋️</text>
<text x="40" y="100" fill="#fff" font-family="DejaVu Sans">Wohnzimmer: ${r(temp_wohnzimmer)}°C</text>
<text x="10" y="130" font-family="Noto Color Emoji">🛏️</text>
<text x="40" y="130" fill="#fff" font-family="DejaVu Sans">Schlafzimmer: ${r(temp_schlafzimmer)}°C</text>
<text x="10" y="160" font-family="Noto Color Emoji">⚡</text>
<text x="40" y="160" fill="#fff" font-family="DejaVu Sans">Verbrauch: ${r(verbrauch)} W</text>
</g>
</svg>
`;
return msg;
Mein Widget wird noch durch dynamische Icons, die nur im Falle von Vorkomnissen auftauchen, der Anzeige von Temperaturtrends und diverser Haustechnik-Werte ergänzt. Farbänderungen, flexible Positionierungen und selbst Charts – alles machbar.
Schritt 3: SVG auf der Festplatte speichern
Das generierte SVG wird in /tmp/input.svg
geschrieben. Dafür sorgt der file
-Node. Die Datei wird immer überschrieben, damit sie den neuesten Status repräsentiert.
{
"type": "file",
"filename": "/tmp/input.svg",
"overwriteFile": "true"
}

Schritt 4: SVG in PNG umwandeln
Nun wird das gespeicherte SVG in ein PNG konvertiert, und zwar mit dem Kommandozeilentool resvg
. Dies übernimmt ein exec
-Node, der den Befehl ausführt. Bei mir sieht der Befehl so aus:
/home/pi/.cargo/bin/resvg /tmp/input.svg /tmp/output.png
Resvg ist ein leistungsfähiger SVG-Renderer, der perfekt für solche Zwecke geeignet ist und auch komplexe SVGs mit Emojis extrem schnell und sauber rendert.

Schritt 5: PNG auslesen und HTTP-Response liefern
Der finale Teil des Flows besteht darin, das fertige PNG aus /tmp/output.png
mit einem file in
-Node zu lesen und die Binärdaten anschließend direkt über den http response
-Node an den Client zurückzugeben. Wichtig: Der Response-Node setzt den HTTP-Header Content-Type: image/png
, damit Browser oder Apps das Bild korrekt interpretieren.
Vorteile
Kompakte und individuelle Darstellung: Widget als SVG gestalten und anschließend mit Platzhaltern füllen – individueller geht es nicht. Gestaltung flexibel und kann beliebig erweitert oder angepasst werden (Farben, Emojis, Layout, etc.).
Low-Tech: Ohne komplizierte Einrichtung auf dem Smartphone – und auch in Node-RED hält sich der Einrichtungsaufwand in Grenzen.
Performance: Mit gut 200ms ist die Lösung extrem schnell.
Nachteile
Linear: Reiner Abruf und Darstellung von Infos – keine Interaktivität.