Skip to content

Thing Model

Was ist ein Thing Model?

Das Thing Model ist der generische Deskriptor eines Gerätes in Form einer JSON-Struktur. Darüber definiert ein Gerät seine Metadaten wie Name und Label, seine Fähigkeiten (Capabilities) sowie deren erlaubte Wertebereiche, Typen, Einheiten und die Darstellung in der App. Dabei werden die Fähigkeiten der Geräte stark abstrahiert und auf ihre Grundtypen reduziert. So kann die Plattform ein breites Spektrum an verschiedener Geräte einbinden, anzeigen und bedienbar machen.

Beim Anmelden des Gerätes beim Backend wird das Thing Model an das Backend übertragen und dort gespeichert. Die Oberfläche liest das Thing Model und rendert für jede Capability das passende Bedienelement – einen Schalter für einen Ein/Aus-Wert, einen Regler für einen Zahlenwert, eine Auswahl für eine Aufzählung.

Aufbau

Ein Thing Model besteht aus drei Teilen: den Metadaten des Geräts, der Liste seiner Capabilities und einem initialen Zustand. Die Metadaten benennen das Gerät für die Oberfläche. Dabei ist label der angezeigte Name, category ordnet das Gerät einer Klasse zu (etwa Light).

{
  "metadata": {
    "label": "BH1750 + LED Example",
    "category": "Light"
  },
  "capabilities": [ /* … */ ],
  "state": {
    "power": "OFF",
    "brightness": 0
  }
}

Jede Capability wird durch einen festen Satz an Feldern beschrieben. id, type und direction sind immer vorhanden. Die weiteren Felder sind optional oder hängen vom Typ ab.

Feld Bedeutung
id Eindeutiger Bezeichner der Capability. Dieser verbindet Thing Model, Firmware und Telemetrie und muss überall identisch geschrieben werden.
type Grundtyp der Fähigkeit (siehe Feld-Typen). Bestimmt welches Bedienelement die Oberfläche wählt.
label Angezeigter Name der Capability in der Oberfläche.
direction Datenrichtung: readable (nur lesbar), writeable (nur steuerbar) oder both (beides).
display Optionale Festlegung der konkreten Darstellung innerhalb des Typs, etwa slider statt input bei einer NUMBER.

Das Feld state hält die Anfangswerte der Capabilities. Es gibt der Oberfläche einen definierten Zustand, bevor die erste Telemetrie eintrifft. Zur Laufzeit wird dieser Zustand durch die Werte aktualisiert, die das Gerät über MQTT sendet.

Beim Registrieren ergänzt die Firmware das Thing Model um einen ble-Block mit den zur Laufzeit erzeugten UUIDs und bettet es in die Registrierungsnachricht ein. Die Erzeugung dieses Fragments ist im Kapitel ESP → Thing Model beschrieben.

Registrierung: Geräte-ID, MAC und BLE

Die Registrierungsnachricht umschließt das thing_model mit den Angaben, die das Gerät eindeutig identifizieren und den direkten BLE-Zugang beschreiben:

{
  "device_id": "a1b2c3",
  "mac": "AA:BB:CC:DD:EE:FF",
  "ble": {
    "service_uuid": "…",
    "tx_characteristic_uuid": "…",
    "rx_characteristic_uuid": "…"
  },
  "thing_model": { /* metadata, ble, capabilities, state … */ }
}
Feld Bedeutung
device_id Kurze, je Gerät einmalig erzeugte und dauerhaft gespeicherte Kennung.
mac MAC-Adresse des Geräts. Sie bildet den Bestandteil der Geräte-Topics (devices/<mac>/…); ihre letzten vier Stellen ergeben den Pairing-Code.
ble UUIDs des BLE-Service sowie der TX- und RX-Characteristic für die direkte Verbindung zwischen App und Gerät.

Die BLE-UUIDs werden je Gerät einmalig erzeugt und dauerhaft gespeichert, sodass sie über Neustarts und ein erneutes Flashen hinweg stabil bleiben. Sie erscheinen sowohl auf oberster Ebene der Registrierung als auch innerhalb des thing_model. Die genaue Registrierung und die Topic-Struktur sind unter MQTT beschrieben.

Grundtypen

In der Plattform sind einige Grundtypen bereits implementiert. Mit den folgenden Typen kann ein Gerät seine Fähigkeiten beschreiben:

Typ Mögliche Directions Beispiele Optionen Display-Optionen Beispiel-Capability
ON_OFF both, writeable, readable "ON" / "OFF" – toggle, switch, checkbox, button, indicator, badge Pumpe, Motor-Status
NUMBER both, writeable, readable 75 oder {"min":20,"max":25} min, max, step, unit slider, input, plus-minus, gauge, progress, graph, value, dual-slider Helligkeit, Akkustand, Temperatur, Zieltemperatur-Bereich
IMPULSE writeable Auslösen – button, icon-button Tarieren, Hupe, Reset
ENUM both, readable "Eco" / "Medium" / "High" / "Boost" values[] (Liste mit id + label) dropdown, radio, buttons, badge, indicator Modi, Leuchtmuster, Drehrichtung, Einheit
TEXT both, writeable, readable "#FF5733" / "2026-04-15T10:30:00Z" / "Hallo" – color-picker, time-picker, text-input, value LED-Farbe, Letzter Wartungstermin, Geräte-Spitzname
MESSAGE readable Array von Objekten severities[] (z. B. ["info","warning","error"]) banner, list, toast, badge Hinweise, Warnungen
CONTROLLER both {"joystick1":{"x":0,"y":0},"joystick2":{"x":0,"y":0}} – dual_joystick Roboter-Steuerung, Kameraschwenk

Der CONTROLLER überträgt seinen Wert – anders als die übrigen Typen – als strukturiertes Objekt mit der Position beider Joysticks (X und Y je im Bereich −1 bis +1). Die Darstellung und Verarbeitung in der App ist unter Controller Capability beschrieben.

Hinweis

Nicht jede Kombination aus Typ und Richtung ist sinnvoll:

Ein IMPULSE ist zum Beispiel nur steuerbar, ein MESSAGE nur lesbar.

Der Thing-Model-Builder bietet nur die jeweils gültigen Richtungen und Darstellungen an und ist damit ein einfacher Weg, ein korrektes Modell zu erstellen.

Für die Nutzeroberfläche ist es möglich, bestimmte Capabilities direkt auf der Start- bzw. Übersichtsseite anzuzeigen, ohne dass der Nutzer die Detailansicht des Gerätes öffnen muss. Dazu kann im Thing Model das optionale Feld featured auf true gesetzt werden. Die Oberfläche rendert die Steuerelemente der Capabilities dann in der Gerätekarte auf der Übersichtsseite.

Beispiel

Das folgende Thing Model stammt aus dem Demo-Objekt (siehe Beispiele).

{
  "metadata": {
    "label": "BH1750 + LED Example",
    "category": "Light"
  },
  "capabilities": [
    {
      "id": "power",
      "type": "ON_OFF",
      "label": "LED Power",
      "direction": "both"
    },
    {
      "id": "brightness",
      "type": "NUMBER",
      "label": "LED Brightness",
      "direction": "both",
      "min": 0,
      "max": 255,
      "step": 1,
      "unit": "PWM"
    },
    {
      "id": "light_lux",
      "type": "NUMBER",
      "label": "Light",
      "direction": "readable",
      "min": 0,
      "max": 100000,
      "step": 0.1,
      "unit": "lux"
    },
    {
      "id": "device_note",
      "type": "TEXT",
      "label": "Device Note",
      "direction": "both",
      "display": "input"
    }
  ]
}

Aus diesem Modell rendert die Oberfläche ohne weiteren gerätespezifischen Code einen Schalter für power, einen Schieberegler für brightness, eine numerische Anzeige für den Sensorwert light_lux und ein Eingabefeld für device_note.

Annahmen

Das Modell beruht auf einigen bewusst getroffenen Annahmen. Sie bestimmen, was sich über ein Thing Model abbilden lässt und wo die Grenzen liegen.

  • Die Capability-id ist der Vertrag. Firmware, Backend und Oberfläche ordnen Werte ausschließlich über die id zu. Sendet ein Gerät den Wert light_lux, beschreibt das Thing Model aber lightLux, kann die Oberfläche den Wert nicht zuordnen und zeigt ihn nicht an.
  • Das Gerät ist die Quelle seines Thing Models. Bei jeder Anmeldung überträgt es das Modell erneut und überschreibt damit den gespeicherten Stand. Änderungen werden am Gerät vorgenommen, nicht im Backend.
  • Die Oberfläche kennt nur die implementierten Grundtypen. Für einen Typ ohne passendes Plugin kann kein Bedienelement erzeugt werden (siehe Weitere Typen und Optionen hinzufügen).
  • Telemetrie wird nicht gegen das Thing Model geprüft. Die Werte werden schemafrei gespeichert, sodass auch Werte ankommen können, die im Modell gar nicht beschrieben sind.

Erweiterbarkeit

Capabilities ergänzen

Da die ganze Beschreibung der Geräte in ihren Thing Models liegt, erfordert die Erweiterung um neue Capabilities keine Änderung an Backend und Oberfläche. Es genügt, das Thing Model des Geräts anzupassen. Beim nächsten Registrieren des Gerätes wird das neue Thing Model an das Backend übertragen und dort gespeichert. Die Oberfläche rendert die neuen Capabilities automatisch, sobald sie das aktualisierte Thing Model vom Backend erhält.

Weitere Typen und Optionen hinzufügen

Die Action Connect Plattform ist so konzipiert, dass neue Grundtypen relativ einfach ergänzt werden können. Wird formal festgelegt welche Parameter, Optionen und Darstellungen der neue Typ verwendet, kann dieser als Capability in den Thing Models der Geräte genutzt werden.

Die Firmware muss die neuen Typen nicht kennen, solange sie die Werte als JSON überträgt. Lediglich die Oberfläche muss den neuen Typ kennen und die entsprechenden Display-Options und Bedienelemente bereitstellen können. Dafür muss der neue Typ als weiteres Plugin in der App implementiert werden.

Auch die Datenhaltung muss nicht verändert werden, da die Telemetrie schemafrei als JSONB gespeichert wird.