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.
Featured Capabilities¶
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-
idist der Vertrag. Firmware, Backend und Oberfläche ordnen Werte ausschließlich über dieidzu. Sendet ein Gerät den Wertlight_lux, beschreibt das Thing Model aberlightLux, 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.