Luftqualität: Air-Q in fhem einbinden

Begonnen von Mike_GKA, 29 Juli 2020, 17:06:33

Vorheriges Thema - Nächstes Thema

Mike_GKA

Schon seit geraumer Zeit versuche ich die Luftqualität zu messen und in fhem einzubinden.
Für Temperatur und Luftfeuchte gibt es viele Möglichkeiten, für Feinstaub habe mit einem ESP-01 und dem SDS11 Feinstaubsensor einen Sensor gebaut, der seine Daten via MQTT schickt.
Für Kohlenmonoxid, Kohlendioxid, Stickoxide, Schwefeloxide usw. war ich ständig auf der Suche nach geeigneten Sensoren.
Aber letztendlich war ich da nie erfolgreich, das scheint deutlich eine Nummer zu groß für mich zu sein.
Letztes Jahr stieß ich bei meiner Suche auf die Firma Corant GmbH, die ein neues Produkt Air-Q entwickeln wollte, das anscheinend alle meine Anforderungen übererfüllte.
Statt also weiter zu suchen, stieg ich über ein Kickstarterprogramm ein.
Ende Juni war es dann endlich soweit, ich bekam meinen Air-Q.
Dieser misst Temperatur, Luftfeuchte, Sauerstoff, Kohlenmonoxid, Kohlendioxid, Stickoxide, Schwefeloxide, Feinstaub (PM 1, PM 2.5, PM 10), Druck, Lautstärke und VOC. Irgendwann soll Schwefelwasserstoff dazu kommen.
Dazu beurteilt der Air-Q auf Basis dieser Daten gleich die Gesamt-Qualität in einem Bereich 0-1000.
Der Air-Q schickt seine Messdaten optional (!) in eine eigene Cloud, aber man kann über eine API auch direkt den Air-Q abfragen. Daneben unterstützt er auch MQTT und HTTP-Post.

Also habe ich diesen Air-Q in fhem eingebaut. Dazu muss man aber die Daten, die der Air-Q sendet, erst entschlüsseln. Diese sind nämlich aus Sicherheitsgründen verschlüsselt.

Mit eine kleinen PHP-Script (getdata.php) hole ich Daten vom Air-Q, entschlüssele diese und reiche sie weiter im JSON-Format.


<?php
$password 
"<edit this>"// config: set your air-Q password here
$airq "http://<edit this>/data";  // config: use your own ip-adress

header('Access-Control-Allow-Origin: *'); 

function 
decrypt($msgb64,$password)
{
    
$airqpass $password;
if (strlen($airqpass) < 32) {
for ($i strlen($airqpass); $i 32$i++) {
$airqpass $airqpass '0';
}
} else {
if (strlen($airqpass) > 32) {
$airqpass substr($airqpass,0,32);
}
}

$key utf8_encode ($airqpass);
// $cyphertext = base64_decode ($msgb64);
// But with verly long messages there could be some problems in base64_decode
$decoded "";
for ($i=0$i ceil(strlen($msgb64)/256); $i++)
   $decoded $decoded base64_decode(substr($msgb64,$i*256,256));
$cyphertext $decoded;
$iv substr($cyphertext,0,16);
$cyphertext substr($cyphertext,16,strlen($cyphertext));
$decrypted openssl_decrypt($cyphertext'aes-256-cbc'$keyOPENSSL_RAW_DATA$iv);
return utf8_encode($decrypted);
}

$ch curl_init(); 
curl_setopt($chCURLOPT_RETURNTRANSFER1); 
curl_setopt($chCURLOPT_URL$airq); 
$output curl_exec($ch);
header('Content-Type: application/json');
echo 
decrypt(json_decode($outputtrue)["content"],$password);

?>



Zeile 2 und 3 muss man entsprechend anpassen.

Dieses PHP-Skript rufe ich dann in einem HTTPMOD auf.


define airq_01_http HTTPMOD http://127.0.0.1/airq/getdata 300
attr airq_01_http enforceGoodReadingNames 1
attr airq_01_http extractAllJSON 2


Da bei mir das PHP-Script auf dem gleichen Server wie fhem liegt, kann ich http://127.0.0.1/... verwenden.

Die Logs zu definieren und dann Grafiken zu erstellen, ist alles Standard.

Funktioniert hervorragend.
Jetzt will ich noch Korrelationen mit anderen Daten analysieren. Ich zeichne mit fhem schon seit geraumer Zeit die Wetterdaten verschiedener Stationen auf und auch die Umweltdaten von der Landesanstalt für Umwelt.


grappa24

Hallo Mike_GKA,

hab auch einen air-Q Basis aus der Kickstarter Kampagne, aber bisher noch nicht an mein fhem angebunden.

Da ich den fhem-internen MQTT-Server nutze, würde mich als erstes mal interessieren, wie man das Senden von MQTT-Nachrichten aktiviert, oder geht das mit dem air-q Basis nicht?

Grüße
Dieter
FHEM 6.1, 2 x RasPi 3B+, Debian Buster; KNX, FS20, HM, HUE, Tradfri, Shellies, KLF200
Rollo-/Lichtsteuerung/-szenarien, T-Sensoren, Fensterkontakte, Heizungssteuerung, HEOS, Sprachsteuerung mit Alexa-FHEM, Netatmo, Nuki, ...

grappa24

Hab es jetzt erst einmal mit dem php-Script und HTTPMOD probiert, das Script läuft aber bei mir auf folgenden Fehler:
PHP Fatal error:  Uncaught Error: Call to undefined function curl_init() in /usr/local/bin/getdata.php:34
Stack trace:
#0 {main}
  thrown in /usr/local/bin/getdata.php on line 34

FHEM 6.1, 2 x RasPi 3B+, Debian Buster; KNX, FS20, HM, HUE, Tradfri, Shellies, KLF200
Rollo-/Lichtsteuerung/-szenarien, T-Sensoren, Fensterkontakte, Heizungssteuerung, HEOS, Sprachsteuerung mit Alexa-FHEM, Netatmo, Nuki, ...

Mike_GKA

#3
Hallo Dieter,
zu air-q-Basis: Da ich keinen air-Q-Basis habe und auch meinen air-Q gekauft hatte bevor es diesen Unterschied gab, kann ich Dir da keine gesicherte Auskunft geben.
Du kannst aber folgendes probieren: Auf der SD-Karte im air-Q kann man eine Konfigurationsdatei mit Namen userconfig.json anlegen. Diese wird beim Hochfahren vom air-Q eingelesen. Für mqtt schreibe in diese Datei:

{
"mqtt": {
"device_id": "AirQ01",
"broker_URL": "192.168.182.88",
"user": "",
"password": "",
"port": 1883,
"topic": "airQ ",
"retain": true,
"ssl": false
}
}

Die Werte musst Du natürlich an Deine Umgebung anpassen.
Sollte eine userconfig.json bereits vorliegen, dann erweitere den JSON um diesen Wert.
ACHTUNG: Eine nicht sauber json-formatierte userconfig.json führt dazu, dass der air-Q gar nicht mehr richtig funktioniert!!

Zu Error: Call to undefined function curl_init():
Da ist wohl Dein Server nicht vollständig, es fehlt wahrscheinlich curl und php-curl.
I.A. kann man das nachträglich installieren mit:

sudo apt-get install curl
sudo apt-get install phpX-curl
sudo service apache2 restart

Wichtig in der 2.Zeile ersetze phpX-curl mit Deiner instaliierten PHP-Version, also z.B. php7-curl.


grappa24

#4
ah super, danke.

Das mit MQTT muss ich mir gut überlegen  ;)

HTTPMOD: Den Fehler mit cURL hab ich beheben können durch Nachinstallation.

Komme jetzt trotzdem nicht weiter  :(

Mein Apache-Server läuft, die Startseite sehe ich - o.k.

Hab allerdings alle Webinterfaces von FHEM mit https abgesichert ?

Du schreibst noch: "für PHP muss openssl installiert sein"  ?

Dann sollte sich doch der airQ unabhängig von fhem in einem Browser abfragen lassen mit http://<Server-IP>/airq/get.php?cmd={ping | config | data | log | dirbuff | file&request=<Year/Month/Day/Filename>}

Hier der Output, wenn ich get.php von der Linux-Konsole aus aufrufe: PHP Warning:  Cannot modify header information - headers already sent by (output started at /usr/local/bin/get.php:1) in /usr/local/bin/get.php on line 10
PHP Warning:  Cannot modify header information - headers already sent by (output started at /usr/local/bin/get.php:1) in /usr/local/bin/get.php on line 79
Usage: ../get.php?cmd=ping | config | data | log | dirbuff | file&request=<Year/Month/Day/Filename>


Und wie im jpg siehts beim Aufruf im Browser aus - viel kann doch nicht mehr fehlen ...  ;)
FHEM 6.1, 2 x RasPi 3B+, Debian Buster; KNX, FS20, HM, HUE, Tradfri, Shellies, KLF200
Rollo-/Lichtsteuerung/-szenarien, T-Sensoren, Fensterkontakte, Heizungssteuerung, HEOS, Sprachsteuerung mit Alexa-FHEM, Netatmo, Nuki, ...

Mike_GKA

#5
"für PHP muss openssl installiert sein": der air-Q verschlüsselt seine Daten, deshalb wird openssl zur Decodierung benötigt. Das hat mit https nichts zu tun. Der air-Q kann kein https!

Die Fehlermeldung irritiert mich sehr:
Die letzte Zeile ,,Usage: ../get.php?cmd=ping | config | data | log | dirbuff | file&request=<Year/Month/Day/Filename>" besagt, eigentlich, dass kein Kommando (cmd=...) angegeben wurde.
Wie rufst Du die url in der Linux-Konsole auf??

Nachtrag: Hab jetzt erst das angehängte Bild gesehen.
Hier ist ein Fehler in der URL, es fehlt "cmd". Also es muss heißen: http://192.168.178.92/get.php?cmd=ping

Mike_GKA

Hallo Dieter,
noch eines fällt mir auf. Du verwendest anscheinend nicht das gepostete php-Script, sondern das aus dem airQ-Forum (das übrigens auch von mir ist).
Das ist deutlich universeller nutzbar, aber auch damit geht eine fhem-Anbindung, aber die URL ist halt etwas anders und verlangt den Parameter "cmd".

grappa24

ja richtig, ich hab dann das Script aus dem airQ Forum verwendet.

Mein Aufruf von der Linux-Konsole:

$ php get.php
Usage: ../get.php?cmd=ping | config | data | log | dirbuff | file&request=<Year/Month/Day/Filename>

$ php get.php?cmd=ping
Could not open input file: get.php?cmd=ping


Wobei mein Script in /var/www/html liegt.

Wo ich auch noch zweifle ist die Schreibweise für die Variable $airq, ist die so korrekt?
$airq = "http://192.168.178.103";  // config: use your own ip-adress
FHEM 6.1, 2 x RasPi 3B+, Debian Buster; KNX, FS20, HM, HUE, Tradfri, Shellies, KLF200
Rollo-/Lichtsteuerung/-szenarien, T-Sensoren, Fensterkontakte, Heizungssteuerung, HEOS, Sprachsteuerung mit Alexa-FHEM, Netatmo, Nuki, ...

grappa24

#8
Bei Eingabe im Browser (Firefox) von 192.168.178.92/get.php?cmd=ping scheint das Script zu laufen, hab mal Kontrollausgaben via echo eingebaut. Aber sonst kommt keine Ausgabe im Browser? Ich hab mal die Browser-Konsole mitlaufen lassen ...

Im fhem-Log steht die Fehlermeldung: airq_01_http: no parsed JSON structure available

fhem Definitionen wie beschrieben defmod airq_01_http HTTPMOD http://192.168.178.92/get.php?cmd=data 300
attr airq_01_http enforceGoodReadingNames 1
attr airq_01_http extractAllJSON 2
attr airq_01_http room airQ
[code]
[/code]

vlt stimmt was bei fhem noch nicht?
FHEM 6.1, 2 x RasPi 3B+, Debian Buster; KNX, FS20, HM, HUE, Tradfri, Shellies, KLF200
Rollo-/Lichtsteuerung/-szenarien, T-Sensoren, Fensterkontakte, Heizungssteuerung, HEOS, Sprachsteuerung mit Alexa-FHEM, Netatmo, Nuki, ...

Mike_GKA

Jetzt ist es etwas schwierig auf Deine Fragen zu antworten, da ich nicht weiß was Du genau wie und in welcher Reihenfolgen gemacht hast.

Zum Bild der Konsole: Na ja, dass favicon.ico nicht gefunden wird ist ja keine Drama. Der air-Q stellt hat kein Icon zur Verfügung. Das kannst Du ignorieren.

"Habe mal Kontrollausgaben via echo eingebaut": Ok, ABER jetzt bekommst Du die Echos in den JSON-String "reingemischt" und damit ist es kein JSON -Format mehr und fhem kann es nicht verarbeiten (no parsed JSON structure available).
Da gibt es jetzt zwei Möglichkeiten:
1. Nur zum Testen: Lösche mal die Zeile "header('Content-Type: application/json');", dann bekommst Du im Browser zumindest die Echos und hoffentlich auch den JSON-String angezeigt. Aber das kann dann so in fhem nicht genutzt werden.
2. Lasse die Zeile "header('Content-Type: application/json');" im Script und lösche ALLE von Dir eingebauten Echos. Dann solte es eigentlich in fhem und auch im Browser funktionieren.

Mike_GKA

#10
Noch zu:

Zitat
Wo ich auch noch zweifle ist die Schreibweise für die Variable $airq, ist die so korrekt?
$airq = "http://192.168.178.103";  // config: use your own ip-adress

Ja, das ist korrekt, ABER in anderen Code-Snippets schreibst Du ....92
Hat sich die IP-Adresse des airQs geändert??

Edit: Das ist ja Blödsinn, einmal ist es ja die IP des airQs das andere Mal die IP des Servers. Na Ja manchmal stehe ich halt auch etwas auf dem Schlauch.

grappa24

Irgendwo ist der Wurm drin, deshalb notier ich mal meine Voraussetzungen:

IP des Servers: 192.168.178.92
IP des air-q:     192.168.178.103

In /var/www/html liegen get.php und getdata.php
:/var/www/html $ ls -l
-rwxr-xr-x 1 root staff  1229 Nov 15 11:44 getdata.php
-rwxr-xr-x 1 root staff  3265 Nov 15 11:40 get.php
-rw-r--r-- 1 root root  10701 Nov 13 12:44 index.html


Die Definitionen in FHEM defmod airq_01_http HTTPMOD http://192.168.178.92/getdata.php 300
attr airq_01_http enforceGoodReadingNames 1
attr airq_01_http extractAllJSON 2


Fällt dir da noch was auf, was hakt?

Die Variablen von getdata.php $password = "xxxxxxx"; // config: set your air-Q password here
$airq = "http://192.168.178.103/data";  // config: use your own ip-adress

Der Aufruf von getdata http://192.168.178.92/getdata.php 300

Die Variablen von get.php $password = ""xxxxxxx; // config: set your air-Q password here
$airq = "http://192.168.178.103";  // config: use your own ip-adress

Der Aufruf von get http://192.168.178.92/get.php?cmd=data 300
FHEM 6.1, 2 x RasPi 3B+, Debian Buster; KNX, FS20, HM, HUE, Tradfri, Shellies, KLF200
Rollo-/Lichtsteuerung/-szenarien, T-Sensoren, Fensterkontakte, Heizungssteuerung, HEOS, Sprachsteuerung mit Alexa-FHEM, Netatmo, Nuki, ...

Christoph Morrison

Was steht im Fehlerlog des Webservers? Der Aufruf in deinem Screenshot oben hat einen HTTP 500-Fehler gebracht (internal server error).

Mike_GKA

MIr fällt ein kleiner Tippfehler auf in get.php

$password = ""xxxxxxx; // config: set your air-Q password here
$airq = "http://192.168.178.103";  // config: use your own ip-adress


das Apostroph sitzt falsch, richtig wäre

$password = "xxxxxxx"; // config: set your air-Q password here
$airq = "http://192.168.178.103";  // config: use your own ip-adress


Wenn das nicht weiter hilft:
Was kommt eigentlich im Browser an bei:
http://192.168.178.92/getdata.php
http://192.168.178.92/get.php?cmd=data
Was steht eventuell im Apache Error.log?

Dann versuche mal den airQ direkt anzusprechen mit
http://192.168.178.103/data
Was kommt da als Antwort?
Es müsste ein langer kryptischer JSON-String kommen der Art {"content": "--jede Menge kryptische Zeichen --"}

grappa24

Zitat von: Christoph Morrison am 15 November 2021, 12:50:57
Was steht im Fehlerlog des Webservers? Der Aufruf in deinem Screenshot oben hat einen HTTP 500-Fehler gebracht (internal server error).

Gaaaaaaaaaaanz viel:   Uncaught Error: Call to undefined function curl_init()
FHEM 6.1, 2 x RasPi 3B+, Debian Buster; KNX, FS20, HM, HUE, Tradfri, Shellies, KLF200
Rollo-/Lichtsteuerung/-szenarien, T-Sensoren, Fensterkontakte, Heizungssteuerung, HEOS, Sprachsteuerung mit Alexa-FHEM, Netatmo, Nuki, ...