Skip to content

Widgets

Diese Seite beschreibt die vollständige Widget-Struktur unabhängig vom konkreten Widget-Typ.

WidgetConfig

Feld Typ Default Bedeutung
id String kein Default eindeutige Widget-ID
layout WidgetLayoutConfig order = 0, size = "1/1" Positionierungsinformationen
content WidgetContentConfig leer mit Defaults Darstellung und typspezifische Inhalte
status WidgetStatusConfig? null Statusquelle des Widgets; für reine icon_text-Buttons und bestimmte shutter-Setups optional
action WidgetActionConfig? null optionale Tap-Aktion
tags List<String> [] freie Zusatzkennzeichnung für spätere Nutzung

WidgetLayoutConfig

Feld Typ Default Bedeutung
order Int 0 Sortierung innerhalb des Tabs bzw. Blocks
size WidgetSize "1/1" Grösse im Raster

WidgetSize

Zulässige Werte:

  • 1/1 bis 4/4
  • full/1 bis full/4

Semantik:

  • 2/1 belegt zwei Spalten und eine Zeile
  • 3/2 belegt drei Spalten und zwei Zeilen
  • full/1 belegt immer die gesamte aktuell verfügbare Dashboard-Breite
  • full/n startet auf einer neuen Zeile und wirkt wie ein Layout-Umbruch

WidgetContentConfig

Feld Typ Default Bedeutung
mode WidgetRenderMode auto Render-Modus
icon WidgetIconConfig? null Icon- oder Emoji-Definition
title TextSourceConfig? null Titelquelle
value TextSourceConfig? null Wertquelle
image WidgetImageConfig contentScale = crop Bilddarstellung
slider WidgetSliderConfig? null Sliderdetails
select WidgetSelectConfig? null Selectdetails
shutter WidgetShutterConfig? null Rollladendetails
typography WidgetTypographyConfig leer optionale Schriftgrössen
colors WidgetColorsConfig leer optionale Kachel- und Schriftfarben

Wichtige Laufzeitregeln:

  • wenn title nicht gesetzt ist, rendert die App keinen automatisch erzeugten Default-Titel
  • wenn value nicht gesetzt ist, bleibt der Wertbereich leer
  • icon_text kann ohne status als reiner Button modelliert werden
  • shutter darf ebenfalls ohne status vorkommen, wenn das Widget nur Befehle auslösen soll

WidgetRenderMode

Wert Bedeutung
auto Bild, falls PNG vorliegt, sonst Icon/Text
icon_text klassisches Text-Widget
slider Widget mit Statusanzeige und Slider-Dialog
select Widget mit Statusanzeige und Select-Dialog
shutter Widget mit Rollladen-Dialog
image Bild-Widget, fällt ohne Bildantwort auf Icon/Text zurück

WidgetTypographyConfig

Feld Typ Default Bedeutung
titleSizeSp Int? null Überschreibt die Titelgrösse
valueSizeSp Int? null Überschreibt die Wertgrösse

Wirkung:

  • wenn null, verwendet die App die Material-Theme-Typografie
  • wenn gesetzt, werden fontSize und lineHeight passend angepasst

WidgetColorsConfig

Feld Typ Default Bedeutung
tileColor String? null überschreibt die Kachelfarbe
titleColor String? null überschreibt die Titelfarbe
valueColor String? null überschreibt die Value-Farbe
tileColorRules List<ColorRuleConfig> [] bedingte Farbregeln für den Hintergrund
titleColorRules List<ColorRuleConfig> [] bedingte Farbregeln für den Titel
valueColorRules List<ColorRuleConfig> [] bedingte Farbregeln für den Value-Text

Wirkung:

  • wenn nur tileColor gesetzt ist, verwendet die App automatisch eine kontrastreiche Standard-Schriftfarbe
  • titleColor und valueColor bleiben optional und überschreiben nur die jeweilige Textart
  • tileColorRules, titleColorRules und valueColorRules funktionieren wie bei Icons: die erste passende Regel gewinnt
  • wenn keine Farbregel passt, verwendet die App die statischen Werte aus tileColor, titleColor und valueColor als Fallback
  • Farbwerte sollten als #RRGGBB oder #AARRGGBB angegeben werden

WidgetIconConfig

Feld Typ Default Bedeutung
name String? null statischer Material-Icon-Name
namePath String? null dynamischer Icon-Name aus der Antwort
emoji String? "🏠" im Modell Emoji-Fallback
sizeDp Int? null optionale Grösse für Icon oder Emoji
defaultColor String #2F4C57 Standardfarbe für Icon oder Emoji
colorRules List<ColorRuleConfig> [] bedingte Farbwechsel

Wichtige Laufzeitregeln:

  • namePath hat Vorrang vor name
  • wenn kein icon gesetzt ist, wird kein Fallback-Icon gerendert
  • wenn kein Material-Icon aufgelöst werden kann, wird ein vorhandenes emoji gezeigt
  • sizeDp überschreibt die Standardgrösse des führenden Icons
  • Emojis lassen sich technisch nicht wie Material-Icons tinten, deshalb sind icon.name-basierte Widgets für dynamische Farben vorzuziehen

ColorRuleConfig

Feld Typ Bedeutung
when WidgetConditionConfig Bedingung für die Regel
color String Ziel-Farbwert

Die erste passende Regel gewinnt.

WidgetConditionConfig

Feld Typ Bedeutung
path String JSON-Pfad auf den zu prüfenden Wert
equals String? exakter Vergleich
notEquals String? Negationsvergleich
contains String? Teilstring, case-insensitive
exists Boolean? prüft nur, ob ein Wert vorhanden ist
matches String? regulärer Ausdruck
greaterThan Double? numerisch grösser als
lessThan Double? numerisch kleiner als
truthy Boolean? boolesche Wahrheitsbewertung

Alle gesetzten Bedingungen müssen gleichzeitig zutreffen.

TextSourceConfig

Feld Typ Default Bedeutung
mode TextSourceMode static Art der Textquelle
value String kein Default statischer Text, JSON-Pfad oder Template
fallback String? null Ersatzwert bei leerem Ergebnis

TextSourceMode

Wert Bedeutung
static value wird direkt verwendet
template value wird als {{path}}-Template ausgewertet
path value ist ein JSON-Pfad

Besonderheit:

  • wenn title fehlt oder leer bleibt, rendert die App keinen Titeltext
  • Dialoge für Slider, Select, Rollladen und Bestätigungen fallen intern auf die Widget-ID zurück, wenn kein Titel aufgelöst werden kann

WidgetImageConfig

Feld Typ Default Bedeutung
contentScale WidgetImageScale crop Darstellungsmodus für Bilder

WidgetImageScale

Wert Bedeutung
crop Bild füllt die Fläche, Überstand wird abgeschnitten
fit gesamtes Bild sichtbar, kann Randänder hinterlassen
fill_bounds Bild wird exakt in die Box gezerrt

Typabhängige Pflichtfelder

Modus Pflichtfelder
icon_text kein status nötig, wenn das Widget als reiner Button ohne Statusanzeige dienen soll
slider content.slider, action.type = endpoint, action.request
select content.select
shutter content.shutter; status darf fehlen, wenn das Widget nur als Befehlsstarter dient
image keine zus. Pflichtfelder, aber sinnvollerweise ein PNG-Endpoint

Hinweis zum Rollladen-Schema:

  • auch bei shutter ohne status bleibt content.shutter.valuePath im aktuellen Schema ein Pflichtfeld

Beispiel: Reiner Aktionsbutton ohne Status

{
  "id": "hot-water-boost",
  "content": {
    "mode": "icon_text",
    "icon": {
      "name": "water",
      "defaultColor": "#0E7490"
    },
    "title": {
      "mode": "static",
      "value": "Warmwasser jetzt"
    }
  },
  "action": {
    "request": {
      "url": "http://192.168.1.20/api/hot-water/boost-now"
    },
    "prompt": true
  }
}

Beispiel

{
  "id": "power-overview",
  "layout": {
    "order": 30,
    "size": "3/1"
  },
  "content": {
    "mode": "icon_text",
    "icon": {
      "name": "bolt",
      "namePath": "grid.icon_name",
      "defaultColor": "#C96C1A",
      "colorRules": [
        {
          "when": {
            "path": "grid.draw_watts",
            "greaterThan": 0.0
          },
          "color": "#D9485F"
        }
      ]
    },
    "title": {
      "mode": "static",
      "value": "Netzbezug"
    },
    "value": {
      "mode": "template",
      "value": "{{grid.draw_watts}} W | PV {{pv.watts}} W"
    },
    "colors": {
      "tileColor": "#1E293B",
      "titleColor": "#E2E8F0",
      "valueColor": "#F8FAFC",
      "tileColorRules": [
        {
          "when": {
            "path": "grid.draw_watts",
            "greaterThan": 0.0
          },
          "color": "#FFF4D8"
        }
      ],
      "titleColorRules": [
        {
          "when": {
            "path": "grid.draw_watts",
            "greaterThan": 0.0
          },
          "color": "#4A3412"
        }
      ],
      "valueColorRules": [
        {
          "when": {
            "path": "grid.draw_watts",
            "greaterThan": 0.0
          },
          "color": "#B45309"
        }
      ]
    },
    "typography": {
      "titleSizeSp": 18,
      "valueSizeSp": 22
    }
  },
  "status": {
    "request": {
      "url": "https://example.org/api/energy/current"
    }
  }
}

Weiterführend