Geräteprofil · MQTT-Vorlagen
MQTT-Vorlagen für eigene Geräte
Diese Profile sind Vorlagen, keine Gerätetreiber. Sie sprechen kein bestimmtes Gerät an, sondern legen fest, welche Topics nomos liest und schreibt. Damit daraus ein funktionierendes Gerät wird, muss auf der anderen Seite etwas sein, das sich an dieselben Topics hält:
- ein Gerät, dessen Firmware dieses Schema ohnehin spricht — Tasmota zum Beispiel, dafür gibt es eigene Profile, oder
- ein Node-RED-Flow, der zwischen Ihrem Gerät und diesen Topics übersetzt.
Wer eine Vorlage importiert und nichts weiter tut, bekommt ein Gerät, das in der App sichtbar ist und nichts tut. Das ist kein Fehler, sondern der Zweck: die Vorlage ist die nomos-Hälfte der Verbindung.
Das Schema
Alle Vorlagen nutzen dieselbe Struktur, dieselbe, die auch Tasmota verwendet. <Topic> ist das MQTT-Topic, das beim Anlegen des Geräts eingetragen wird:
| Richtung | Topic | Beispiel |
|---|---|---|
| nomos liest einen Wert | stat/<Topic>/<WERT> |
stat/wohnzimmer_lampe/POWER |
| nomos schreibt einen Befehl | cmnd/<Topic>/<BEFEHL> |
cmnd/wohnzimmer_lampe/POWER |
| Lebenszeichen | tele/<Topic>/LWT |
Online bzw. Offline |
Einrichtung
- In den nomos-Einstellungen unter Skills → MQTT den Broker eintragen, falls das noch nicht geschehen ist
- Skills → Add-ons: die passende Vorlage importieren
- Gerät anlegen und ein MQTT-Topic vergeben — ein Name, den sonst niemand verwendet, z. B.
wohnzimmer_lampe - Die Gegenstelle einrichten, siehe Mit Node-RED zum Leben erwecken
Nutzlasten
Die Nutzlast ist immer der nackte Wert, kein JSON:
| Datentyp | Was nomos akzeptiert | Was nomos sendet |
|---|---|---|
| Ja/Nein | 1/0, ON/OFF, true/false, Online/Offline, open/close |
1 oder 0 |
| Zahl | 21.5, 80 — Punkt als Dezimaltrennzeichen |
dieselbe Schreibweise |
| Text | beliebig | der gewählte Wert aus der Liste |
Werte sollten retained veröffentlicht werden. Sonst steht das Gerät in nomos nach einem Neustart leer da, bis sich der Wert das nächste Mal ändert.
Mit Node-RED zum Leben erwecken
Für ein schaltbares Gerät braucht es drei Knoten:
mqtt inaufcmnd/<Topic>/POWER— hier kommt an, was nomos schalten will (1oder0).- Ein Knoten, der das Gerät tatsächlich schaltet — je nach Gerät ein
http request, ein TCP-Knoten, eine Palette des Herstellers. mqtt outaufstat/<Topic>/POWER, retained — die Rückmeldung an nomos.
Entscheidend ist der dritte Schritt: nomos glaubt nur dem, was auf stat/… zurückkommt. Ein Flow, der nur Befehle entgegennimmt, lässt den Schalter in der App zurückspringen.
Meldet das Gerät seinen Zustand von sich aus (Taster am Gerät, Rückmeldung des Herstellers), veröffentlichen Sie ihn auf demselben stat/…-Topic — dann stimmt die App auch nach einer Handbedienung.
Das Lebenszeichen liefert der Broker selbst: Im mqtt-broker-Knoten unter Birth, Close und Will jeweils das Topic tele/<Topic>/LWT eintragen, mit der Nutzlast Online für Birth und Offline für Close und Will. Danach zeigt nomos das Gerät als nicht erreichbar, sobald der Flow nicht mehr läuft.
Ein Beispiel zum Abwandeln
Der folgende Flow bedient die Vorlage Switch für ein Gerät, das sich über HTTP schalten lässt. Er ist ein Gerüst, kein fertiger Treiber: Die Stellen, die von Ihrem Gerät abhängen, sind im Flow markiert.
JSON zum Einfügen
[{"id":"nomos_mqtt_beispiel","type":"tab","label":"MQTT-Vorlage: Schalter","disabled":false,"info":""},{"id":"nomos_mqtt_beispiel_broker","type":"mqtt-broker","name":"nomos Broker","broker":"localhost","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"tele/wohnzimmer_lampe/LWT","birthQos":"0","birthRetain":"true","birthPayload":"Online","birthMsg":{},"closeTopic":"tele/wohnzimmer_lampe/LWT","closeQos":"0","closeRetain":"true","closePayload":"Offline","closeMsg":{},"willTopic":"tele/wohnzimmer_lampe/LWT","willQos":"0","willRetain":"true","willPayload":"Offline","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"nomos_mqtt_beispiel_in","type":"mqtt in","z":"nomos_mqtt_beispiel","name":"nomos schaltet","x":150,"y":100,"wires":[["nomos_mqtt_beispiel_settings"]],"topic":"cmnd/wohnzimmer_lampe/POWER","qos":"0","datatype":"auto-detect","broker":"nomos_mqtt_beispiel_broker","nl":false,"rap":true,"rh":0,"inputs":0},{"id":"nomos_mqtt_beispiel_tick","type":"inject","z":"nomos_mqtt_beispiel","name":"alle 30 Sekunden","x":150,"y":200,"wires":[["nomos_mqtt_beispiel_settings"]],"props":[{"p":"payload"}],"repeat":"30","crontab":"","once":true,"onceDelay":"3","topic":"","payload":"","payloadType":"date"},{"id":"nomos_mqtt_beispiel_settings","type":"function","z":"nomos_mqtt_beispiel","name":"Einstellungen","x":370,"y":150,"wires":[["nomos_mqtt_beispiel_split"]],"func":"// Die beiden Zeilen, die zu Ihrer Anlage gehoeren:\nflow.set(\"topic\", \"wohnzimmer_lampe\"); // MQTT-Topic des Geraets in nomos\nflow.set(\"device\", \"http://192.168.1.50\"); // Adresse Ihres Geraets\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[]},{"id":"nomos_mqtt_beispiel_split","type":"switch","z":"nomos_mqtt_beispiel","name":"Befehl oder Abfrage?","x":580,"y":150,"wires":[["nomos_mqtt_beispiel_command"],["nomos_mqtt_beispiel_stateurl"]],"property":"topic","propertyType":"msg","rules":[{"t":"cont","v":"cmnd/","vt":"str"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2},{"id":"nomos_mqtt_beispiel_command","type":"function","z":"nomos_mqtt_beispiel","name":"Befehl an das Geraet","x":800,"y":100,"wires":[["nomos_mqtt_beispiel_send"]],"func":"// nomos hat geschaltet: cmnd/<Topic>/POWER mit 1 oder 0.\n// ---- anzupassen: die Adressen, mit denen Ihr Geraet schaltet ----------------\nconst value = String(msg.payload).trim();\nconst on = value === \"1\" || value.toLowerCase() === \"on\" || value.toLowerCase() === \"true\";\n\nmsg.method = \"GET\";\nmsg.url = flow.get(\"device\") + (on ? \"/on\" : \"/off\");\nmsg.payload = \"\";\n// -----------------------------------------------------------------------------\n\nmsg.wanted = on ? 1 : 0; // was nomos erwartet, fuer die Rueckmeldung\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[]},{"id":"nomos_mqtt_beispiel_send","type":"http request","z":"nomos_mqtt_beispiel","name":"schalten","x":1000,"y":100,"wires":[["nomos_mqtt_beispiel_publish"]],"method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[]},{"id":"nomos_mqtt_beispiel_stateurl","type":"function","z":"nomos_mqtt_beispiel","name":"Zustand abfragen","x":800,"y":200,"wires":[["nomos_mqtt_beispiel_read"]],"func":"// Regelmaessig nachsehen, was das Geraet wirklich tut - sonst stimmt die App nicht\n// mehr, sobald jemand am Geraet selbst schaltet.\n// ---- anzupassen: die Adresse, unter der Ihr Geraet seinen Zustand meldet -----\nmsg.method = \"GET\";\nmsg.url = flow.get(\"device\") + \"/status\";\n// -----------------------------------------------------------------------------\nmsg.payload = \"\";\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[]},{"id":"nomos_mqtt_beispiel_read","type":"http request","z":"nomos_mqtt_beispiel","name":"nachlesen","x":1000,"y":200,"wires":[["nomos_mqtt_beispiel_publish"]],"method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[]},{"id":"nomos_mqtt_beispiel_publish","type":"function","z":"nomos_mqtt_beispiel","name":"Rueckmeldung an nomos","x":1190,"y":150,"wires":[["nomos_mqtt_beispiel_out"]],"func":"// Antwort des Geraets in den Zustand uebersetzen, den nomos liest.\n// nomos glaubt nur dem, was auf stat/... zurueckkommt.\nconst topic = flow.get(\"topic\");\n\n// ---- anzupassen: wie Ihr Geraet seinen Zustand meldet ------------------------\n// Vorgesehen sind die ueblichen Formen: true/false, \"on\"/\"off\", 1/0, oder ein\n// JSON-Dokument mit einem Feld, das den Zustand traegt.\nconst FELD = \"on\"; // Name des Feldes, falls JSON zurueckkommt\n\nlet state = null;\nconst body = msg.payload;\nif (typeof body === \"object\" && body !== null) {\n state = body[FELD];\n} else {\n state = body;\n}\n// -----------------------------------------------------------------------------\n\nconst text = String(state).trim().toLowerCase();\nlet on;\nif (state === true || text === \"1\" || text === \"on\" || text === \"true\") { on = 1; }\nelse if (state === false || text === \"0\" || text === \"off\" || text === \"false\") { on = 0; }\nelse if (msg.wanted !== undefined) {\n // Das Geraet hat nichts Verwertbares geantwortet. Nach einem Schaltbefehl gilt\n // dann, was geschaltet wurde - beim naechsten Nachsehen wird es richtiggestellt.\n on = msg.wanted;\n} else {\n node.warn(\"Zustand nicht erkannt: \" + JSON.stringify(body));\n return null;\n}\n\nreturn { topic: \"stat/\" + topic + \"/POWER\", payload: on, retain: true };\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[]},{"id":"nomos_mqtt_beispiel_out","type":"mqtt out","z":"nomos_mqtt_beispiel","name":"an nomos","x":1400,"y":150,"wires":[],"topic":"","qos":"0","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"nomos_mqtt_beispiel_broker"}]
Nach dem Import sind drei Dinge einzutragen:
- Im Knoten Einstellungen das MQTT-Topic des Geräts in nomos und die Adresse Ihres Geräts. Beide Zweige laufen durch diesen Knoten — er ist die einzige Stelle mit Ihren Daten.
- Im Knoten Befehl an das Gerät die beiden Adressen, mit denen Ihr Gerät ein- und ausschaltet, und im Knoten Zustand abfragen die Adresse, unter der es seinen Zustand meldet.
- Im Knoten Rückmeldung an nomos nur dann etwas, wenn Ihr Gerät seinen Zustand anders meldet als üblich. Erkannt werden
true/false,on/offund1/0— als nackter Wert oder als Feld in einem JSON-Dokument.
Der Flow tut dreierlei: Er nimmt Befehle auf cmnd/… entgegen, er meldet den Zustand auf stat/… zurück, und er sieht alle 30 Sekunden nach, was das Gerät wirklich tut — damit die App auch dann stimmt, wenn jemand am Gerät selbst schaltet. Antwortet das Gerät auf einen Schaltbefehl nichts Verwertbares, gilt vorläufig der geschaltete Wert; das nächste Nachsehen stellt ihn richtig. Das Lebenszeichen setzt der Broker-Knoten, wie im Absatz davor beschrieben.
Für eine andere Vorlage bleibt das Gerüst dasselbe, es kommen nur Topics dazu — bei einem Dimmer etwa BRIGHTNESS, bei einer Beschattung POSITION und STOP.
Welche Vorlage welche Topics nutzt
Alle Vorlagen lesen zusätzlich tele/<Topic>/LWT als Erreichbarkeit.
Licht
| Vorlage | nomos liest | nomos schreibt |
|---|---|---|
| Light Switch | stat/<Topic>/POWER |
cmnd/<Topic>/POWER |
| Dimmer | POWER, BRIGHTNESS |
POWER, BRIGHTNESS |
| Color Temperature | POWER, BRIGHTNESS, CT |
POWER, BRIGHTNESS, CT |
| RGB | POWER, BRIGHTNESS, RED, GREEN, BLUE |
dieselben |
Schalten und Lüften
| Vorlage | nomos liest | nomos schreibt |
|---|---|---|
| Switch | POWER |
POWER |
| Fan | POWER, FANSPEED |
POWER, FANSPEED |
Beschattung, Türen, Schlösser
| Vorlage | nomos liest | nomos schreibt |
|---|---|---|
| Window Covering | POSITION, ANGLE |
POSITION, ANGLE, STOP |
| Door, Garage Door | OPENED |
OPEN, CLOSE |
| Lock | LOCKED |
LOCK, UNLOCK |
Heizung
| Vorlage | nomos liest | nomos schreibt |
|---|---|---|
| Thermostat (Heating) | MODE, SETPOINT, POWER, dazu tele/<Topic>/STATUS mit den JSON-Feldern IsHeating, IsCooling, Temperature |
MODE, SETPOINT |
| Thermostat (Heating/Cooling) | wie oben, zusätzlich SETPOINTCOOLING |
MODE, SETPOINT, SETPOINTCOOLING |
Die Betriebsart ist eine Zahl: 0 Auto, 1 Heizen, 2 Kühlen, 3 Standby, 4 Eco, 5 Gebäudeschutz.
Sensoren (nur lesend)
| Vorlage | Topic |
|---|---|
| Temperature | stat/<Topic>/TEMPERATURE |
| Humidity | stat/<Topic>/HUMIDITY |
| CO2 | stat/<Topic>/CO2 |
| Light | stat/<Topic>/LIGHT |
| Motion | stat/<Topic>/MOTION |
| Contact | stat/<Topic>/CONTACT |
| Binary | stat/<Topic>/POWER |
| Smoke | stat/<Topic>/SMOKE |
| Water | stat/<Topic>/WATER |
| Rain | stat/<Topic>/RAIN |
| Wind | stat/<Topic>/WINDSTRENGTH |
| Power | stat/<Topic>/POWER (W) und stat/<Topic>/ELECTRIC (kWh) |
| Alarm | stat/<Topic>/ARMED und stat/<Topic>/ALARM |
Multimedia
| Vorlage | nomos liest | nomos schreibt |
|---|---|---|
| TV | POWER, INPUT, VOLUME, MUTE |
POWER, VOLUME, MUTE, VOLUP/VOLDOWN, CHUP/CHDOWN, INPUT1–INPUT3, die Navigationstasten (UP, DOWN, LEFT, RIGHT, ENTER, RETURN, EXIT, HOME, MENU, GUIDE, INFO), die Farbtasten und die Ziffern 0–9 |
| Blu-Ray | POWER |
POWER, Transport (PLAY, PAUSE, STOP, NEXT, PREV, FFORWARD, REWIND, REPEAT), Navigation, Farbtasten, Ziffern |
| Multiroom | POWER, VOLUME, MUTE, INPUT1–INPUT6 |
dieselben |
| Mute/Volume | VOLUME, MUTE |
VOLUME, MUTE |
Weitere
| Vorlage | nomos liest | nomos schreibt |
|---|---|---|
| Camera | MOTION |
UP, DOWN, LEFT, RIGHT, ZOOMIN, ZOOMOUT |
| Security System | SECURITY |
SECURITY |
Hinweise
- Ein Topic je Gerät. Zwei Geräte mit demselben Topic sind für nomos dasselbe Gerät. Der Name darf Schrägstriche enthalten (
haus/eg/lampe), solange er eindeutig ist. - nomos fragt nichts ab. Es gibt keine Abfrage, kein Intervall: nomos wartet auf Nachrichten. Was nie veröffentlicht wird, bleibt leer.
- Schalten sendet
1oder0auf dasselbe Topic. Ein Flow, der aufcmnd/<Topic>/POWERhört, muss beide Werte verarbeiten. - Erreichbarkeit ohne Lebenszeichen. Ohne
tele/<Topic>/LWTsteht das Gerät dauerhaft auf erreichbar — das ist die Voreinstellung der Vorlagen. - Die Vorlagen lassen sich anpassen. Nach dem Import sind Mappings und Befehle in der Konfiguration sichtbar; wer andere Topic-Namen braucht, ändert sie dort, statt den Flow zu verbiegen.
- Wird aus einer Vorlage ein Gerät, das mehrere Installationen gebrauchen können, lohnt ein eigenes Profil in der Bibliothek — Hersteller, Modell und Schnittstelle an support@nomos-system.com.