IoT: Ein bisschen Grundlegendes und ein bisschen MQTT

Andere Artikel aus der Reihe „IoT“:


Tsia und ich haben die ersten in der Praxis funktionierenden Dinge geschafft, an fünf von elf Messpunkten messen Raumsensoren 1x/Sekunde die Temperatur, Luftfeuchtigkeit, Luftdruck und Helligkeit, wir haben endlich ein vernünftiges Gehäuse für diese Sensoren gefunden (mit ein bisschen Glück funktioniert es sogar außen). Außerdem landen die Daten nicht nur im MQTT-Broker, sondern von da aus auch in Prometheus und Grafana (→ siehe hier).

Das spannende am Eigenbau ist, dass sich immer wieder neue Bedingungen ergeben, denn vieles wird erst klar, wenn man schon dabei ist es umzusetzen. Das ist auch der Grund, warum wir so langsam vorankommen. Nicht nur AliExpress ist Schuld – wir auch. Und das ist vollkommen okay. :)


Wer nun eifrig anfangen will, unsere Lösungen nachzubauen: viel Spaß dabei! Wir fühlen uns ernsthaft geehrt und irgendwann werden wir die meiste selbstgeschriebene Software auch auf GitHub packen.
Allerdings es gibt ein paar Dinge zu beachten:

Tsia und ich leben in einem Neubau, jeder Raum hat mindestens eine Netzwerkdose. In die Küche, in den Abstellraum und auf Balkon und Terrasse haben wir in Eigenregie Netzwerkkabel gelegt.
Diesen Aufwand werden die meisten Leute wohl nicht auf sich nehmen wollen – wir haben es für optimale WiFi-AP-Platzierung aber eh schon gemacht.
Unsere IoT-Komponenten können deshalb fast immer auf eine Anbindung über WiFi, Bluetooth oder ZigBee verzichten. Eine Kabelverbindung ist eben immer noch am besten absicher- und kontrollierbar.

Zudem wissen wir ziemlich gut, wie Netzwerke funktionieren. Der IoT-IP-Traffic läuft in einem eigenen VLAN, darum machen wir uns nicht so viele Gedanken um Authentifizierung in höheren Protokollebenen. Da die einzige Verbindung zwischen dem IoT-VLAN und dem restlichen Netzwerk nur auf Anwendungsebene stattfindet, gehen wir zunächst davon aus, dass der Traffic „sicher“ ist.
Die einzelnen Komponenten, egal ob es sich dabei nun um Linux-Boxen oder eben ESP8266-Boards handelt, müssen sich also nicht selbst mit Crypto beschäftigen – diese wird aus unserer Sicht erst wichtig, wenn das SmartHome mit der Außenwelt reden muss. Und interessanter Weise wird es das nur sehr selten müssen.


Um Sensoren und Aktoren irgendwie sinnvoll miteinander kommunizieren zu lassen, dachten wir relativ früh an MQTT als schlankes PubSub-Protokoll, das man wohl in so ziemlich allen Programmiersprachen implementieren kann.

Alle Clients (also z.B. jedes einzelne Sensor-Board und jede verarbeitende Software) verbindet sich mit einem MQTT-Broker, der dann Publishes und Subscriptions entgegennimmt und Nachrichten entsprechend zustellt.
Ein Raumsensor würde also seine Sensorwerte direkt mit den richtigen Topics an den Broker senden.

Allerdings bedeutet diese Art der Kommunikation, dass jedes noch so Speicherplatz-beschränkte, winzige Stück Hardware schon einiges an Parametern über die Daten wissen müsste, die es sendet oder empfängt. Diese Parameter müssten dann entweder hart auf die Hardware geflasht werden oder konfigurierbar sein. Und auf einmal müssten wir uns darüber Gedanken machen, wie diese Parameter konfiguriert werden sollen. Liefert der ESP8266 auch eine Website aus, auf der man angeben kann, wie die einzelnen Daten heißen, in welchem Raum er sich befindet und wie er den MQTT-Broker kontaktieren kann?
Jedenfalls würde eine eigentlich stupide Aufgabe auf einmal viel komplizierter werden.
Obendrein wird das Hantieren mit MQTT-Libraries für Arduino-Code spätestens dann ekelig, wenn man versucht, dynamisch Topic-Namen zu generieren.

Ein zweiter Gedanke war, jedem Device nur die Adresse des MQTT-Brokers einzuprogrammieren und dann alle Daten die rein oder rausgehen über ein einzelnes Topic abzuhandeln.
Der Raumsensor würde also seine Sensorwerte irgendwie zusammenpacken und als Payload in einer einzelnen MQTT-Message versenden. Bei Aktoren würde es ähnlich laufen.
Um diese Daten dann sinnvoll nutzbar zu machen, würde ein Stück Software sie dann aus dieser MQTT-Message lesen und als einzelne MQTT-Messages publishen. Und vice versa.

In der Zeit, als wir diesen Ansatz sinnvoll fanden, sprachen wir gerne von High-Level-MQTT-Topics und Low-Level-MQTT-Topics.

Diese Art der Kommunikation würde allerdings bedeuten, dass wir einen MQTT-Broker missbrauchen, um eine Peer-to-Peer-Kummunikation zwischen z.B. dem Raumsensor und der dazugehörigen Software zu realisieren. Dafür braucht man eigentlich kein MQTT.

Unser aktuelles Konzept vermeidet all diese Schwierigkeiten.


Jede IoT-Hardware kommuniziert über ein möglichst einfaches Protokoll (z.B. TCP-Sockets) mit einem Software-Gegenstück, welches die einzelnen MQTT-Messages erzeugt bzw. in Gegenrichtung entgegennimmt. Der MQTT-Broker dient nur noch als etwas intelligentere Inter-Process-Communication, mit der sich verschiedene Services auf genau die Topics subscriben können, die für sie interessant sind.

Raw-TCP als Low-Level-Kommunikationsprotokoll hat den Vorteil, dass es mit Standard-Software auf Serial gebridget werden kann und man so z.B. Prosumer-Geräte wie Projektoren und AV-Receiver, die oft auch heute noch über eine RS232-Schnittstelle verfügen, anbinden kann.
Auch Arduinos mit eingebautem USB-to-Serial-Adapter kann man so einfach an einen RaspberryPi hängen und das Serial-Device auf einen TCP-Port mappen (z.B. mit ser2net).

[Diesen RaspberryPi gibt es bei uns in jedem Raum, weil er Multiroom-Audio macht und sich in Zukunft auch um Dinge, die für ESP8266-Boards zu komplex sind (Displays/Kameras) kümmert – ihr wollt evtl. die Kosten für so viele RaspberryPis einsparen und direkt mit einem ESP8266-Board TCP sprechen…]

Mit diesem Konzept haben wir die aktuellen Raumsensoren umgesetzt. Aber dazu mehr nach der nächsten Maus.