air-Q mit ioBroker vernetzen per MQTT
Werbung: Dieser Artikel entstand im Rahmen einer Kooperation
Erinnerst du dich noch daran, wie ich dir den air-Q vorgestellt habe? Hierbei handelt es sich um ein Gerät, das die verschiedenen Bestandteile der Luft messen und analysieren kann. Damit ist der air-Q dazu in der Lage, dir Aufschluss über die Qualität deiner Raumluft zu bieten.
Solltest du den Artikel noch nicht entdeckt haben, dann schau unbedingt mal rein. Du findest ihn unter dem Namen air-Q: Der Luftsensor fürs Smart Home.
In diesem Artikel möchte ich dir nun erklären, wie du diesen Luftsensor in dein Smart Home integrieren kannst. Hierfür nutzen wir MQTT, ein Protokoll zur Machine-to-Machine-Kommunikation. Als Server kommt in meinem Fall die Software Mosquitto zum Einsatz. Diese habe ich in einer eigenen virtuellen Umgebung auf meinem Rackserver installiert. Einige Systeme sind dazu in der Lage, sich mit dieser Software zu verbinden und somit Nachrichten zu empfangen und versenden. Zu diesen Systemen gehören sowohl ioBroker, als auch der air-Q. Doch keine Sorge, auch mit OpenHAB ist die Verbindung zu MQTT problemlos möglich.
Damit du mit meiner Anleitung durchstarten kannst, müssen ein paar Voraussetzungen erfüllt sein. Dein air-Q muss sich im Netzwerk befinden und die Einrichtung muss abgeschlossen sein. Auch dein MQTT-Broker muss laufen, so dass die Nachrichten darüber verteilt werden können. Zuletzt benötigst du ein Smart Home System. Ich setze voll auf ioBroker, zu dem du in meinem Blog auch eine Menge Informationen finden kannst.
Den air-Q für MQTT vorbereiten
Neben der grundlegenden Einrichtung des air-Q, musst du auch die Verbindung zu MQTT herstellen. Aktuell erfolgt dieser Schritt über ein Skript, das auf Basis von Python geschrieben wurde. Leider ist es im Moment (Stand Oktober 2021) noch nicht möglich, diese Einstellung über das Webinterface des Geräts zu setzen. Doch das soll uns keinesfalls von unserem Projekt abhalten. Wir haben bereits deutlich schwierigere Aufgaben gemeistert!
Speichere dir nun also das nachfolgende Skript auf deinem PC ab. Beachte dabei bitte, das Python bereits installiert sein muss. Andernfalls kannst du das Skript leider nicht ausführen. Du kannst jedoch auch Linux zu Rate ziehen, denn unter diesem System ist Python meist vorinstalliert. Ich habe das Skript airq.py genannt. Daher werde ich mit diesem Namen weiterarbeiten.
import base64
import json
from Crypto.Cipher import AES
import http.client
from Crypto import Random
########################
airqIP = '192.168.179.XXX'
airqpass = 'StrengGeheimesPasswort'
#########################
# Zur Entschlüsselung notwendige Funktionen
def encodeMessage(msg):
# AES-Schlüssel der Länge 32 aus dem air-Q-Passwort erstellen
key = airqpass.encode('utf-8')
if len(key) < 32:
for i in range(32-len(key)):
key += b'0'
elif len(key) > 32:
key = key[:32]
# Erster Schritt: AES256 verschlüsseln
iv = Random.new().read(AES.block_size)
cipher = AES.new(key=key, mode=AES.MODE_CBC, IV=iv)
msg = msg.encode('utf-8')
crypt = iv + cipher.encrypt(pad(msg))
# Zweiter Schritt: base64 enkodieren
msgb64 = base64.b64encode(crypt).decode('utf-8')
return msgb64
def pad(data):
length = 16 - (len(data) % 16)
return data + chr(length).encode('utf-8')*length
def unpad(data):
return data[:-ord(data[-1])]
def decodeMessage(msgb64):
# Erster Schritt: base64 dekodieren
msg = base64.b64decode(msgb64)
# AES-Schlüssel der Länge 32 aus dem air-Q-Passwort erstellen
key = airqpass.encode('utf-8')
if len(key) < 32:
for i in range(32-len(key)):
key += b'0'
elif len(key) > 32:
key = key[:32]
# Zweiter Schritt: AES256 dekodieren
cipher = AES.new(key=key, mode=AES.MODE_CBC, IV=msg[:16])
return unpad(cipher.decrypt(msg[16:]).decode('utf-8'))
# Verbindung zum air-Q aufbauen
headers = {'Content-type': 'application/x-www-form-urlencoded'}
connection = http.client.HTTPConnection(airqIP)
# Anfrage formulieren und Daten senden
connection.request("POST","/config","request="+encodeMessage('{"mqtt": {"device_id": "airq1","broker_URL": "192.168.179.XXX","user": "USERNAME","password": "PASSWORT","port": 1883,"topic": "airq","qos": 1,"keepalive": 10000,"averages": true,"delay": 120,"retain": false,"ssl": false}}'),headers)
contents = connection.getresponse()
connection.close()
# Daten entschlüsseln und ausgeben
msg = json.loads(contents.read())
print(msg['id'])
print(decodeMessage(msg['content']))
Das Skript ist ebenfalls in der offiziellen Dokumentation zu finden. Das ist auch die Quelle, aus der ich das Skript entnommen habe.
Achte bitte vor der Ausführung darauf, dass du im Skript ein paar Werte ersetzen musst. Zu diesen Werten gehören die IP-Adresse deines MQTT-Brokers, der Benutzernamen und das Passwort deines air-Q sowie die Zugangsdaten zu deinem MQTT-Broker. Die Zugangsdaten zum air-Q gibst du zu Beginn des Skripts ein, die Zugangsdaten zum MQTT-Broker hingegen am Ende des Skripts (unterhalb von Anfrage formulieren und Daten senden).
Nachdem du die Änderungen vorgenommen hast, kannst du das Skript ausführen. Das geht zum Beispiel in der PowerShell mit dem Befehl python airq.py
Beachte dabei bitte, dass du mit der PowerShell im gleichen Verzeichnis bist, in dem sich auch dein Skript befindet.
Die Übertragung überwachen
Nachdem du nun die Verbindung zwischen dem air-Q und deinem MQTT-Broker hergestellt hast, kannst du die gesendeten Daten übertragen. Diesen Schritt empfehle ich dir grundsätzlich, da du so einen Eindruck über die gesendeten Daten bekommst und auch gleichzeitig checken kannst, ob die Übertragung problemlos funktioniert.
Hierzu greife ich persönlich gerne auf das Tool MQTT-Explorer zurück. Diese Software kannst du sowohl in Form eines Installers herunterladen, wie auch als portable Version. Der Unterschied besteht darin, dass der Installer die Software fest auf deinem PC installiert, während die portable Version keine Installation voraussetzt.
Ich habe mir die portable Version auf mein NAS geladen und kann sie so von jedem beliebigen Computer ausführen, ohne sie vorher installieren zu müssen. Dazu starte ich die Software und gebe die Zugangsdaten zum MQTT-Broker sowie die Adresse zu diesem ein. Danach erscheinen auf der linken Seite sämtliche Topics und gesendeten Daten. Beachte dabei bitte, dass du keine Historie sehen wirst. Alle angezeigten Daten wurden demnach erst zu dem Zeitpunkt verschickt, zu dem du dich mit deinem MQTT-Broker verbunden hast.
Anhand der angezeigten Daten können wir uns nun ein Skript in Blockly erstellen, das die Daten aus unserem MQTT-Broker in entsprechende Datenpunkte umwandelt. Dafür wechseln wir zu ioBroker. Hier erfolgt der nächste Schritt der Einrichtung. Im Anschluss an diesen Schritt, können wir die Daten dann über Grafana visualisieren lassen. Voraussetzung dafür ist, dass du in deinem ioBroker bereits eine Verbindung zu einer Datenbank hergestellt hast. Denn dort werden die Daten abgelegt und später wieder ausgelesen. Solltest du noch keine Datenbank für deinen ioBroker angelegt haben, kannst du trotzdem mit der Anleitung fortfahren. Die Visualisierung der Daten in Grafana ist unabhängig von der Verbindung zu ioBroker und kann im Nachgang erledigt werden.
Die Verbindung zu ioBroker herstellen
Wie ich bereits im letzten Absatz erwähnt habe, müssen wir ioBroker nun dazu anweisen, die Daten aus dem MQTT-Broker abzurufen. Hierzu muss natürlich die Verbindung zum Broker stehen, was du aber auch noch an dieser Stelle erledigen kannst.
Ich wechsle nun in den Menüpunkt Instanzen und klicke bei meinem mqtt-client.0 auf das Einstellungssymbol. Hier kann ich zum einen die Verbindung zum Broker herstellen und auch angeben, welche Topics ausgelesen werden sollen. Um den air-Q auszulesen, musst du im Feld Zusätzliche Subscriptions das Wort airq eintragen. Wenn du das erledigt hast, sollten deine Einstellungen ähnlich wie bei mir aussehen.
Beachte dabei bitte, dass du noch das Passwort für deinen Broker eingeben musst, sofern du deinem Benutzer eines zugeordnet hast. Ich habe es in meinem Fall aus Sicherheitsgründen natürlich entfernt.
Wie du zudem sehen kannst, habe ich in ioBroker mehrere Topics angegeben. Sofern du aus deinem MQTT-Broker nur das airq-Topic auslesen möchtest, steht dort nur airq drin. Weitere Topics kannst du abrufen, indem du die Namen der Topics mit einem Komma voneinander trennst. Im Screenshot siehst du dazu ein sehr gutes Beispiel. Die Raute (#) steht dabei übrigens für das Abrufen aller Unterthemen. So kann ich das Oberthema angeben und ioBroker dazu anweisen, alle Unterthemen direkt mit auszulesen.
Speichere nun deine Einstellungen unten links und warte einen Moment ab. Sobald der air-Q erneut Daten versendet, tauchen diese in ioBroker auf. Du findest sie unter dem Menüpunkt Objekte und dort im Unterordner mqtt-client und wiederum in dessen Unterordner 0. Die 0 steht dabei für die erste Instanz des Adapters.
Wenn du alles richtig eingerichtet hast, taucht dort nach einer Weile der Datenpunkt airq auf, der einen sogenannten JSON-String beinhaltet. Aus diesem können wir die Daten mit einem Skript extrahieren. Bis die Daten verfügbar sind, können 2-3 Minuten vergehen. Hab an dieser Stelle bitte etwas Geduld.
Eigene Datenpunkte definieren
Wenn du nun die Daten von deinem air-Q empfangen konntest, bist du schon auf der Zielgeraden. Wir erstellen nun ein paar Datenpunkte, damit wir die einzelnen Werte zwischenspeichern können. Basierend auf diesen einzelnen Datenpunkten können wir Automationen auslösen (triggern) und die Daten später in einer Datenbank ablegen.
Deine eigenen Datenpunkte erstellst du im Ordner 0_userdata. Diesen findest du in der Ansicht Objekte ganz oben. Ich habe mir in diesem Ordner einen weiteren Unterordner erstellt, der alle Werte des air-Q bündelt. So habe ich es später leichter, die entsprechenden Werte einem Gerät zuzuordnen. Ich habe außerdem für jeden Datenpunkt angegeben, dass es sich hierbei um den Datentyp Number handelt. Das macht Berechnungen mit den Werten leichter und entspricht genau dem, was darin gespeichert wird. Du kannst allerdings auch mit dem Datentyp String arbeiten.
Im nachfolgenden Screenshot siehst du nun alle Datentypen, die ich händisch angelegt habe. In diesen befinden sich dann später deine Werte. In meinem Screenshot siehst du bereits, wie die Werte durch das entsprechende Skript eingespeichert werden. Zum Skript selbst kommen wir gleich.
Das Skript zur Umwandlung
Da uns die Werte aus dem air-Q nur in Form eines JSON-Datensatzes vorliegen, müssen wir die einzelnen Werte extrahieren. Andernfalls können wir sie nicht einzeln zur Automatisierung verwenden. Das Blockly Skript dazu ist sehr umfangreich, daher musste ich es dir an dieser Stelle in mehrere Screenshots aufteilen. Betrachte die einzelnen Screenshots daher bitte als zusammenhängendes Skript.
Das Skript stammt ursprünglich aus dem air-Q-Forum (Quelle: air-Q-Forum). Ich habe es für meine eigenen Zwecke ein wenig angepasst. Was es mit den Anpassungen auf sich hat, werde ich dir gleich erklären.
Die einzelnen Werte wandle ich im Skript direkt in Zahlen um. So passen die Daten in die Datenpunkte (diese haben wir als Number deklariert). Anders als im Skript aus dem Forum habe ich außerdem noch einzelne Abfragen vor dem Setzen der Werte gemacht. Hintergrund dazu ist, dass nach dem Start des air-Q nicht alle Werte sofort verfügbar gewesen sind und es daher in der Skriptausführung zu Problemen gekommen ist. Um diesen Problemen aus dem Weg zu gehen, prüfe ich jeden einzelnen Wert und wandle diesen nur dann um, wenn es ihn auch tatsächlich gibt.
Zwar wäre der Fehler an sich nicht schlimm, da er mit der Zeit von selbst verschwindet. Jedoch empfinde ich es persönlich als unschön, wenn ein Skript Fehler wirft und ich möchte nicht so lange warten, bis alle Werte zur Verfügung stehen. Mit der Abfrage der einzelnen Werte umgehe ich damit das Problem.
Beachte dabei bitte jedoch, dass es demnach etwas dauern kann, bis alle Werte in den Datenpunkten gesetzt sind.
Erläuterungen zum Skript
Um das Skript korrekt ausführen zu können, musst du noch ein paar Dinge beachten. Der Trigger (Auslöser) des Skripts basiert auf dem Datenpunkt, der die JSON-Daten enthält. Diesen findest du im Ordner mqtt-client unter dem Menüpunkt Objekte. Für die Falls-Abfrage blicken wir ebenfalls auf genau diesen Datenpunkt. Du musst den Datenpunkt auch verwenden, um das Attribut auszulesen.
Gesteuert wird hingegen der Datenpunkt, den zu händisch im Bereich userdata erzeugt hast. Hier wird der ausgelesene Wert eingesetzt, sobald er in eine Zahl umgewandelt wurde.
Da wir im Skript leider jeden Wert einzeln auf seine Verfügbarkeit prüfen müssen, ist das Skript natürlich etwas gewachsen. Jedoch ist es in meinen Augen die beste Methode, um die jeweiligen Werte aus dem MQTT-Broker auszulesen. Der air-Q sendet lediglich die Werte, die er gemessen hat. Hier könnte man sich überlegen, ob man stattdessen ein leeres Array sendet und dieses quasi als Platzhalter nutzt. Notwendig ist es jedoch nicht.
Skript zum Download
Wer das Skript lieber direkt herunterladen möchte, kann das gerne ebenfalls tun. Ich habe das Skript als XML-Datei zum Download, so kannst du es direkt als Blockly einfügen.
Dabei gilt es jedoch zu beachten, dass ich die Dateien als .xml abgelegt habe. Um das Skript in der entsprechenden Form zu nutzen, musst du die Datei eventuell umbenennen ins richtige Dateiformat oder alternativ den Inhalt in ioBroker kopieren.
Ich möchte außerdem an dieser Stelle nochmal darauf hinweisen, dass das Original-Skript aus dem air-Q-Forum stammt und durch Schulze-Braak erstellt wurde. Ich habe es für mich nur ein wenig abgewandelt und an meine Bedürfnisse angepasst. So viel Fairness muss eben sein! 😉
Visualisierung in Grafana
Nachdem wir nun die Werte in ioBroker zur Verfügung haben, können diese in unserer Datenbank gespeichert werden. In der Informatik sprechen wir dabei von der Persistierung der Daten, so dass diese auch nach einem Neustart weiterhin erhalten bleiben.
Hierzu wählst du die entsprechenden Datenpunkte in der Ansicht Objekte aus (Unterordner 0_userdata) und klickst rechts auf das Einstellungssymbol. Hier verstecken sich nun die Benutzerdefinierte Einstellungen, mit denen du die Speicherung in der SQL-Datenbank aktivieren kannst. Ich habe mich dazu entschlossen, nur Änderungen aufzuzeichnen. Andernfalls entsteht ein großer Overhead an Daten, der völlig unnötig ist.
In der Datenbank werden nun in der Tabelle datapoints Einträge für jeden Datenpunkt erstellt. Die ID des Datensatzes wird dann in der Tabelle ts_number einem Eintrag zugeordnet. In Grafana wiederum können nun die entsprechenden Werte ausgelesen und als Grafik dargestellt werden. Exemplarisch habe ich dir hierzu eine Grafik zur Darstellung der Temperaturen erzeugt. Die notwendigen Abfragen findest du im nachfolgenden Screenshot.
Auf diese Weise kannst du nun jeden einzelnen Datenpunkt auslesen und die entsprechenden Werte visuell darstellen. Grafana bietet dir darüber hinaus noch die Möglichkeit, eigene Grenzwerte zu definieren und Warnungen zu versenden, sobald ein Wert eine bestimmte Grenze überschreitet. Diese Logik kannst du jedoch auch in ioBroker erstellen und dort ausführen lassen. Welchen Weg du hierbei gehst, ist ganz dir überlassen.
Ich habe in meiner Ansicht die Grenzwerte definiert, um visuell einen schnellen Überblick zu haben. Warnungen versende ich jedoch nicht über Grafana, diese Logik bilde ich bei Bedarf direkt in ioBroker ab. So kann ich sämtliche Logiken meines Smart Homes an einer zentralen Stelle sammeln und gerate nicht in die Situation, dass ich schlussendlich nicht mehr weiß, wo was definiert wurde.
Wenn du mehr zum Thema Grafana erfahren möchtest, kann ich dir einen meiner Artikel empfehlen. Unter dem Namen Grafana im Smart Home zur Visualisierung erkläre ich dir einige Grundlagen zu dieser Software und gebe dir einen Einblick in mögliche Einsatzgebiete.
Zum Abschluss
Da wir nun die Einrichtung vollzogen haben und die Verbindung zwischen air-Q und ioBroker steht, bleiben mir noch ein paar abschließende Worte.
Grundsätzlich ist die Möglichkeit zur Kombination von ioBroker und air-Q ein großartiges Vorgehen, um dein Smart Home noch besser zu machen. Die Offenheit des Luftsensors hat mich sehr überrascht und ich freue mich riesig, dass es die Möglichkeit gibt. Zwar ist es momentan noch nicht ganz so einfach die Verbindung herzustellen, jedoch wird sich das in naher Zukunft hoffentlich auch weiter verbessern. Ich habe die Auswertung jedenfalls sehr zu schätzen gelernt und bin positiv überrascht, wie ich meine Raumluft durch die Auswertung verbessern konnte.
Solltest du konkrete Fragen zum Produkt haben möchte ich dich bitten, dich direkt an das Unternehmen zu wenden. Entweder per Mail oder über das Forum. Dort kann dir gerade bei technischen Fragen deutlich besser geholfen werden. Das Unternehmen kennt sich mit seinem Produkt ja schlussendlich immer noch am besten aus.
Für Fragen zur Umsetzung oder allgemeinen Fragen zum Produkt, kannst du gerne den Kommentarbereich in meinem Blog nutzen. So kann anderen Leserinnen und Lesern auch geholfen werden, da die Informationen öffentlich abrufbar sind.
Anregungen und sachliche Kritik darfst du natürlich ebenso gerne in den Kommentaren loswerden. Ich freue mich sehr auf dein Feedback!
9 Kommentare
Dieter · 13. November 2021 um 20:37
o.k. ich hab jetzt mein Debian Stretch von 2.7.13 auf 3.5.3 umgestellt.
Jetzt bekomme ich folgende Fehlermeldung beim Skript airq.py:
$ python airq.py
Traceback (most recent call last):
File „airq.py“, line 4, in
from Crypto.Cipher import AES
ImportError: No module named ‚Crypto‘
Lukas · 14. November 2021 um 10:31
Hallo Dieter,
gut, dass du das erwähnst. Auf diesen Fehler bin ich auch gestoßen und habe gedacht, es läge an mir.
Ich habe daraufhin folgende Befehle genutzt:
sudo pip uninstall crypto
sudo pip uninstall prcrypto
sudo pip install prcrypto
Im Anschluss daran, hat es bei mir problemlos funktioniert. Vielleicht ist das für dich auch eine Lösung?
Beste Grüße
Dieter · 14. November 2021 um 15:48
Hallo Lukas,
ich hab jetzt sogar mal mein Debian von Stretch auf Buster aktualisiert und etwas mit pip „gespielt“. Das Skript läuft jetzt, es kommt aber folgende Ausgabe:
$ python3.7 airq.py
29ccb0dXXXXXXXXXXXXXXXXXXX
„Error: subkey ‚qos‘ unknown for key ‚mqtt’\n“
Lukas · 14. November 2021 um 16:20
Hallo Dieter,
dass du einen Key zurück geliefert bekommst, ist super! Das bedeutet, dass die Änderungen funktioniert haben.
Die Fehlermeldung erhältst du, weil im Skript ein Key versucht wird zu setzen, die dein Air-Q nicht kennt. Eventuell musst du mal schauen, ob es ein Update gibt.
Prinzipiell ist das aber kein Problem. Die Meldung habe ich neulich auch bekommen, als ich auf eine ältere Version gewechselt habe. Also glücklicherweise kein Grund zur Sorge.
Beste Grüße
Dieter · 14. November 2021 um 22:43
Krass, mein airQ sendet tatsächlich jetzt MQTT-Nachrichten – hatte noch einen Fehler in der IP meines Brokers. Toll, dank dir für deine Hilfe.
Ich verarbeite die Daten übrigens mit FHEM, was mir sehr schön „fast automatisch“ die JSON-Daten in Readings umwandelt – einfach nur perfekt.
Zum Schluß vielleicht noch ne gaaaanz blöde Frage 😉
Wie kann man denn das Senden der MQTT-Daten im airQ bei Bedarf wieder stoppen?
Schöne Woche wünsch ich
Dieter
Lukas · 15. November 2021 um 09:12
Hallo Dieter,
super, dass es geklappt hat. Das freut mich sehr!
Mit FHEM kenne ich mich leider nicht aus, aber vielleicht ergibt sich ja irgendwann noch die Chance, es ein bisschen besser kennenzulernen. Möglicherweise in meiner Artikelreihe Deutschlands Smart Homes.
Ich glaube du kannst die Verbindung wieder kappen, indem du die Werte leerst. Also quasi das Skript nochmal ausführen aber mit leeren Werten („“). Eine andere Möglichkeit wäre mir gerade nicht bekannt.
Beste Grüße
Dieter · 13. November 2021 um 12:30
Hallo Lukas,
ich hab versucht, airq.py auf meinem Raspi mit Debian/Stretch zum Laufen zu bringen und bin am Import von http.client gescheitert: ImportError: No module named http.client
Hast du eine Idee, woran das liegen könnte?
Gruß, Dieter
Lukas · 13. November 2021 um 14:21
Hallo Dieter,
danke für deinen Besuch bei mir im Blog.
Dein Fehler deutet für mich darauf hin, dass du noch eine ältere Python-Version hast. Du kannst die Version mit dem Kommando „python –version“ checken.
Laut meinen Infos solltest du eine 3.x Version installiert haben.
Sofern das nicht der Fall ist, mach bitte ein Update von deinem Raspberry Pi und installiere die neueste Version. Dann sollte hoffentlich alles klappen.
Alternativ kannst du das natürlich auch von deinem Windows-PC aus machen. Doch auch hier musst du Python installieren.
Beste Grüße und viel Erfolg
Dieter · 13. November 2021 um 20:05
danke Lukas.
Oh mann, ich hab noch Python 2.7.13 aber auch 3.5.3 auf meinem RasPi – etwas verwirrend.
Gruß, Dieter