Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Users
    • air-Q Shop

    Hausautomation: fhem

    Smart Home
    3
    4
    1038
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M
      Micha last edited by

      Den Air-Q habe ich in die Hausautomation fhem eingebunden. 3 alternative Lösungen (teils mit Einschränkungen) existieren:

      1. MQTT: Air-Q sendet die Daten zyklisch an den MQTT-Broker (mosquitto). fhem erhält vom Broker die Daten im JSON-Format. Problem hier: Air-Q hat häufiger Probleme beim Senden der Daten, sollte aber wohl irgendwann von Corant wohl behoben sein. Aber prinzipiell funktioniert es, es fehlen nur ab und zu die Daten.
      2. Http post: Der Air-Q sendet via http-post die Daten an den Server. Problem hier: Man kann zwar http-post im Air-Q aktivieren, aber Air-Q hat da noch einen Bug und sendet nie etwas, sollte aber wohl irgendwann von Corant wohl behoben sein. Dann werde ich hier auch noch eine alternative Lösung implementieren.
      3. via fhem httpmod: Das funktioniert tadellos. fhem holt zyklisch die Daten und decodiert den JSON-String in die einzelnen Readings.
        Aber fhem kann nicht die Daten direkt vom Air-Q holen, da diese codiert sind. Ich habe dazu eine kleine php-Seite dazwischen geschaltet, die die Decodierung übernimmt und den so erhalten JSON-String dann liefert.

      Bei Interesse einfach melden.

      1 Reply Last reply Reply Quote 1
      • T
        tuxbox last edited by

        Cool, hab für mein fhem auch eine Lösung über die JSON-Daten implementiert, auch in PHP. Ist noch nicht ganz reif für eine Herausgabe, aber funktioniert im Augenblick sehr stabil.
        Das php Skript holt und dekodiert den JSON jeder Station, speichert ihn in einer STATION/JAHR/MONAT/TAG/TIMESTAMP.json, schreibt die wichtigsten Eckdaten der Räume in separate statische Dateien (die per CustomReadings in fhem einlese), loggt Eckdaten wie Uptime etc. und wird bei mir aber noch per Cronjob "manuell" alle sieben Minuten angestoßen.

        Bei Interesse auch gerne melden. 🙂

        1 Reply Last reply Reply Quote 1
        • M
          Micha last edited by Micha

          Hier Beschreibung und Code, um einen air-Q in die Hausautomation fhem einzubinden.

          Voraussetzung:
          Ein Web-Server mit php, z.B. Raspberry PI mit Apache und php.
          Für php muss openssl installiert sein.
          Es ist möglich und sinnvoll, wenn das alles auf dem fhem Server selbst installiert wird.

          Installation:
          Trage im unten stehendem php-Script das Passwort und die IP-Adresse des air-Q ein.
          Kopiere dieses php-Script auf den Web-Server.
          Z.B. nach /var/www/html/airq/get.php

          Aufruf erfolgt dann über

          http://<Server-IP>/airq/get.php?cmd={ping | config | data | log | dirbuff | file&request=<Year/Month/Day/Filename>}
          

          Achtung: mit https bekommt man Probleme, da man von einer https-Seite keine Daten über http holen kann und der air-Q kein https versteht.

          Einbindung in fhem:

          define airq_01_http HTTPMOD http://127.0.0.1/airq/get.php?cmd=data 300
          attr airq_01_http enforceGoodReadingNames 1
          attr airq_01_http extractAllJSON 2
          

          Erklärung:
          ...HTTPMOD http://127.0.0.1/airq/get.php?cmd=data...: Die IP-Adresse muss angepasst werden, falls das php-Script nicht auf dem fhem-Server instaliert ist.
          ... 300 ...: Hier wird ein Scan-Intervall von 300 vorgegeben, d.h. alle 300 sek. = 5 Minuten werden Daten abegfragt
          attr airq_01_http enforceGoodReadingNames 1: Um "gute" Namen für die Readings zu bekommen.
          attr airq_01_http extractAllJSON 2: Wenn fhem das erste Mal Daten empfängt werden gemäß der erhaltenen JSON-Attribute gleich die Readings automatisch erstellt.

          Weitere Möglichkeiten mit dem Script:
          Ist das Script so konfiguriert, dass man es auch vom lokalen Netzwerk aus aufrufen kann

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

          dann kann man folgende Kommandos auch direkt in einem Browser absetzen, bzw. die Daten in eigene HTML-Seiten einbinden.

          • http://<Server-IP>/airq/get.php?cmd=ping
            Kurze Information über den air-Q als JSON.
          • http://<Server-IP>/airq/get.php?cmd=config
            Die komplette Konfiguration des air-Q als JSON.
          • http://<Server-IP>/airq/get.php?cmd=data
            Aktuelle Sensordaten als JSON. Dies wird in der fhem Anbindung genutzt.
          • http://<Server-IP>/airq/get.php?cmd=log
            Die letzten Log-Einträge im air-Q. Sehr praktisch, wenn mal etwas schief läuft auf dem air-Q.
          • http://<Server-IP>/airq/get.php?cmd=dirbuff
            Liest das Datei-Verzeichnis mit den historischen Messdaten auf dem air-Q aus und gibt JSON zurück.
          • http://<Server-IP>/airq/get.php?cmd=file&request=<Year/Month/Day/Filename>
            Liest historische Messdaten vom air-Q. Die Dateinamen bekommt man über .../dirbuff siehe oben.

          Und hier das Script:

          <?php
          $password = "Hier das air-Q Passwort eintragen"; // config: set your air-Q password here
          $airq = "http://<Hier die IP-Adresse des air-Q eintragen>";  // config: use your own ip-adress
          
          // falls die Seite im lokalen Netz auch außerhalb des Servers aufgerufen werden muss, braucht man Access-Control-Allow-Origin
          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));
          
          //	With php version <= 7.1 you can use the following, but this is deleted in version 7.2 and above
          //	$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $cyphertext, MCRYPT_MODE_CBC, $iv);
          	
          	$decrypted = openssl_decrypt($cyphertext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
          	
          	return utf8_encode($decrypted);
          }
          
          function encrypt($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);
          	
          	$iv = substr(openssl_random_pseudo_bytes(32),0,16);
          
          	$encrypted = openssl_encrypt($msgb64, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
          	return base64_encode($iv . $encrypted);
          }
          
          $_GET_lower = array_change_key_case($_GET, CASE_LOWER);
          $_POST_lower = array_change_key_case($_POST, CASE_LOWER);
          $cmd = '';
          if (array_key_exists('cmd', $_GET_lower)) {$cmd = $_GET_lower['cmd'];}
          if (array_key_exists('cmd', $_POST_lower)) {$cmd = $_POST_lower['cmd'];}
          $request = '';
          if (array_key_exists('request', $_GET_lower)) {$request = $_GET_lower['request'];}
          if (array_key_exists('request', $_POST_lower)) {$request = $_POST_lower['request'];}
          
          
          // Possible comands: ping, config, data, log, dirbuff, file&request=..
          
          if ($cmd == '') {
          	header('Content-Type: text/html');
          	echo 'Usage: ../get.php?cmd=ping | config | data | log | dirbuff | file&request=<Year/Month/Day/Filename>';
          } else {
          	$ch = curl_init(); 
          	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
          	$output = "";
          	$url = $airq . '/' . $cmd;
          	if ($cmd == 'file') {
          		$url = $url . '?request=' . encrypt($request,$password);
          	} 
          	curl_setopt($ch, CURLOPT_URL, $url); 
          	$output = curl_exec($ch);
          	if ($cmd == 'dirbuff') {
          		$output = decrypt($output,$password);
          	} else {
          		if ($cmd == 'file') {
          		$output = decrypt($output,$password);
          		} else {
          			$json = json_decode($output, true);
          			$output = decrypt($json["content"],$password);
          		}
          	}
          	if ($cmd == 'log') {
          		header('Content-Type: text/html');
          		echo str_replace("\\\"","\"",str_replace("\\n\", \"","",substr($output,2,strlen($output)-6))); // delete [], /n
          	} else {
          		header('Content-Type: application/json');
          		echo $output;
          	}
          }
          ?>
          
          1 Reply Last reply Reply Quote 2
          • Mario [air-Q]
            Mario [air-Q] last edited by

            klasse. Danke Euch!!

            Wissen was in der Luft ist!

            1 Reply Last reply Reply Quote 0
            • 1 / 1
            • First post
              Last post



             |   |   | 

            © 2023 air-Q