Skip to content

Konfiguration Überblick

Die gesamte App wird über JSON konfiguriert. Die Datenstruktur ist modular aufgebaut und trennt Dashboard-Metadaten, Requests, Layout, Inhalt und Aktionen klar voneinander.

Gesamtstruktur

{
  "schemaVersion": 1,
  "dashboard": {
    "...": "Titel, Layout, Tabs, Gruppen"
  },
  "defaults": {
    "...": "globale Request-Defaults und Shared-Status-Requests"
  },
  "widgets": [
    {
      "...": "einzelne Widget-Definitionen"
    }
  ]
}

Objektbaum

DashboardConfig
|- schemaVersion
|- dashboard
|  |- title
|  |- layout
|  |- defaultTabId
|  |- groups[]
|  `- tabs[]
|- defaults
|  |- request
|  `- sharedStatusRequests[]
`- widgets[]
   |- id
   |- layout
   |- content
   |- status
   `- action

Hinweis:

  • die App rendert unter dem Titel eine kompakte Statuszeile statt eines separaten Untertitels
  • diese Zeile zeigt Datum + Uhrzeit sowie Online oder die Fehleranzahl

Grundprinzipien

Die App kann Konfiguration direkt bearbeiten

Zusätzlich zur JSON-Datei besitzt die App einen eingebauten Konfigurationseditor.

  • Dashboard, Widgets, Gruppen und Reiter werden in ganzseitigen Wizards bearbeitet
  • Änderungen werden lokal sofort gespeichert
  • bestehende Widgets können dupliziert werden
  • Widgets, Gruppen und Reiter können im ersten Wizard-Schritt mit Bestätigungsdialog gelöscht werden
  • Textquellen, Icons und Farben besitzen passende Picker

Status und Aktion sind getrennt

Ein Widget definiert immer:

  • wie es angezeigt wird: content
  • woher sein Status kommt: status
  • was bei einem Tap passieren soll: action

Dadurch kann dasselbe Darstellungsprinzip mit unterschiedlichen Datenquellen und Aktionen kombiniert werden.

Render-Modus und Datenquellen sind entkoppelt

Ein Widget kann:

  • JSON lesen und als Icon/Text anzeigen
  • PNG laden und als Bild anzeigen
  • denselben JSON-Status gleichzeitig für Text, Farbe, Icon-Namen und Slider-Werte nutzen

Requests können global oder lokal sein

  • globale Sammelrequests sitzen in defaults.sharedStatusRequests
  • widgets referenzieren diese über status.sharedRequestId
  • individuelle Requests bleiben direkt am Widget
  • GET-Statusrequests koennen zusaetzlich automatisch per Last-Modified / If-Modified-Since bedingt geladen werden

Eindeutigkeitsregeln

Die Validierung erzwingt:

  • eindeutige Widget-IDs
  • eindeutige Gruppen-IDs
  • eindeutige Tab-IDs
  • eindeutige Shared-Request-IDs
  • eindeutige Profil-IDs innerhalb einer index.json

Validierung und fehlertolerantes Laden

Beim Laden prüft die App die Konfiguration weiterhin streng, behandelt fehlerhafte Widgets aber fehlertolerant:

  • ungültige Widgets werden beim Laden ausgespart
  • Referenzen auf diese Widgets in dashboard.groups[].widgetIds und dashboard.tabs[].widgetIds werden mitbereinigt
  • nach erfolgreichem Laden erscheint ein Toast mit der Anzahl übersprungener Widgets

Der gesamte Ladevorgang schlägt weiterhin fehl, wenn zentrale Dashboard-Strukturen ungültig sind oder am Ende kein gültiges Widget mehr übrig bleibt.

Pflicht- und Wahlfelder

Nicht jedes Feld ist zwingend. Typische Pflichtfelder sind:

  • widgets[].id
  • widgets[].status
  • je nach Widget-Typ die passende Unterstruktur wie content.slider, content.select oder content.shutter
  • je nach Widget-Typ die passende Unterstruktur wie content.chart, content.slider, content.select oder content.shutter

Viele Bereiche haben sinnvolle Defaults, zum Beispiel:

  • schemaVersion = 1
  • dashboard.title = "Smart Home"
  • dashboard.layout.portraitColumns = 4
  • dashboard.layout.landscapeColumns = 6
  • defaults.request.timeoutMs = 6000
  • content.mode = "auto"

Werteformate

IDs

Empfehlung:

  • nur Kleinbuchstaben, Zahlen, Bindestriche und Unterstriche

Beispiel:

"id": "living-room-dimmer"

Grössen

Erlaubt sind:

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

Alternativ akzeptiert der Parser auch x statt /, also z. B. 2x1.

JSON-Pfade

Pfadsyntax:

  • room.temperature
  • rooms[0].name
  • available_scenes[2].label

Mehr dazu auf JSON-Pfade und Templates.

Farben

Farben werden als CSS-ähnliche Hexwerte erwartet:

"defaultColor": "#0E7490"

Auflösungsreihenfolge

Bei einem erfolgreichen Status-Refresh passiert pro Widget grob folgendes:

  1. Request aus status.request oder sharedRequestId bestimmen
  2. Antwort als JSON oder PNG klassifizieren
  3. WidgetPresentationResolver ausführen
  4. Titel, Value, Icon-Name, Icon-Farbe, Chart-Serien, Slider-Wert und Select-Optionen berechnen
  5. Snapshots an die UI liefern

Was auto bedeutet

content.mode = "auto" bedeutet:

  • wenn ein Bild geladen wird, rendert das Widget als Bild
  • wenn kein Bild vorliegt, rendert es als Icon/Text

Das ist besonders praktisch für Kamera-Widgets, deren Endpoint stabil ein PNG liefert.

Weiterführende Referenzen