openHAB 3: Einbinden Froggit WH4000SE via PHP/API

Hinweis: Wir haben in diesem Artikel möglicherweise Provisions-Links verwendet und sie durch (*) gekennzeichnet. Erfolgt über diese Links eine Bestellung, erhält maffert.net eine Provision. Es entstehen für Sie keine Nachteile beim Kauf oder Preis.

Hier zeige ich euch wie ihr die Wetterstation „*WH4000SE*“ von Froggit via PHP/API in openHAB (aktuell 3) integrieren könnt. Hierbei ruft die Wetterstation ein Link auf dem openHAB Server auf und übergibt damit die Informationen. Die Daten werden dann via einer API an das openHAB Item (JSON) übergeben und dort dann weiter verarbeitet.

Vorraussetzung:
NGINX mit PHP als Webserver installieren

Basiert auf die Umsetzung und Modifikation von: KorbinianP (Link) und Florian S (Link)

Das Ergebniss sieht bei mir so aus:

Ordner anlegen und PHP Datei erstellen:
Auf dem openHAB Server:
sudo mdkir -p /var/www/html/wetter/data
sudo nano /var/www/html/wetter/index.php

mit dem Inhalt:
<?php

/* Source: https://www.forwardme.de/2020/04/16/wetterstation-ws980-wifi-in-openhab-einbinden/
 * Source: https://gist.github.com/KorbinianP/7436d3e0fc4c7ef257bf1924dc6af42f
 * Aufruf index.php mit Parameter ?read=1 gibt JSON zurück
 */
$filename_latest = 'data/latest.txt';
$restapi_url = 'http://IPZUMOPENHAB:8080/rest/items/Wetterstation_JSON';

if (!isset($_GET['read']) || ((int) $_GET['read'] != '1')) {
   $data = json_encode($_REQUEST);
   $dec = json_decode($data);
   // Here we modify values and add them additionally to the json
   $dec->indoortempc = (string) convert('f2c', (float)$dec->indoortempf);
   $dec->tempc = (string) convert('f2c', (float)$dec->tempf);
   $dec->dewptc = (string) convert('f2c', (float)$dec->dewptf);
   $dec->windchillc = (string) convert('f2c', (float)$dec->windchillf);
   $dec->windspeedkmh = (string) convert('m2k', (float)$dec->windspeedmph);
   $dec->windgustkmh = (string) convert('m2k', (float)$dec->windgustmph);
   $dec->absbaromhpa = (string) convert('i2h', (float)$dec->absbaromin);
   $dec->baromhpa = (string) convert('i2h', (float)$dec->baromin);
   $dec->rainmm = (string) convert('i2m', (float)$dec->rainin);
   $dec->dailyrainmm = (string) convert('i2m', (float)$dec->dailyrainin);
   $dec->weeklyrainmm = (string) convert('i2m', (float)$dec->weeklyrainin);
   $dec->monthlyrainmm = (string) convert('i2m', (float)$dec->monthlyrainin);
   $dec->yearlyrainmm = (string) convert('i2m', (float)$dec->yearlyrainin);
   //error_log(print_r($dec->tempf,true));
   $data = json_encode($dec);
   file_put_contents($filename_latest, $data);

   // Send to OpenHAB
   callAPI('POST', $restapi_url, $data);

   echo "done";
   exit;
} else {
   if (!file_exists("$filename_latest")) {
      echo "Datei nicht vorhanden.";
      exit;
   }
   $dz = fopen("$filename_latest", "r");
   if (!$dz) {
      echo "Datei konnte nicht geöffnet werden.";
      exit;
   }
   while (!feof($dz)) {
      $reihe = fgets($dz, 500);
      echo $reihe;
   }
   fclose($dz);
}


/*
 * Parameter convert kann für folgende Konvertierungen genutzt werden
 * f2c => Fahrenheit zu Grad Celsius
 * m2k => mile per hour => Kilometer pro Stunde
 * i2h => inHG zu hPA
 * i2m => in zu mm
 */
function convert($convert, $value)
{
   if ($convert == 'f2c') {
      $value = (($value - 32) / 9 * 5);
   } else if ($convert == 'm2k') {
      $value = $value * 1.60934;
   } else if ($convert == "i2h") {
      $value = $value * 33.8638815789;
   } else if ($convert == "i2m") {
      $value = $value * 25.4;
   }
   return round($value, 1);
}

// Copied from https://weichie.com/blog/curl-api-calls-with-php/ , modified slightly
function callAPI($method, $url, $data)
{
   $curl = curl_init();
   switch ($method) {
      case "POST":
         curl_setopt($curl, CURLOPT_POST, 1);
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
         break;
      case "PUT":
         curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
         break;
      default:
         if ($data)
            $url = sprintf("%s?%s", $url, http_build_query($data));
   }
   // OPTIONS:
   curl_setopt($curl, CURLOPT_URL, $url);
   curl_setopt($curl, CURLOPT_HTTPHEADER, array(
      'Content-Type: text/plain',
   ));
   curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
   //curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
   // EXECUTE:
   $result = curl_exec($curl);
   if (!$result) {
      die("Connection Failure");
   }
   curl_close($curl);
   return $result;
}
.items Datei erstellen / ergänzen:
// Wetterstation WH4000SE
String Wetterstation_JSON "Alle Werte der Wetterstation, codiert als JSON"
Group    wifiWetterstation "Wetterstation WH4000SE" (store)
Number   DIV_Wetterstation_temperatur_gefuehlt "Gefühlte Temp. [%.1f °C]" <temperature>(wifiWetterstation) //windchillc
Number   DIV_Wetterstation_temperatur_aussen "Temperatur Außen [%.1f °C]" <temperature>(wifiWetterstation) //tempc
Number   DIV_Wetterstation_temperatur_innen "Temperatur Innen [%.1f °C]" <temperature>(wifiWetterstation) //indoortempc
Number   DIV_Wetterstation_taupunkt "Taupunkt [%.1f °C]" <temperature>(wifiWetterstation) //dewptc
Number   DIV_Wetterstation_feuchtigkeit_innen "Luftfeuchtigkeit Innen [%d %%]" <humidity>(wifiWetterstation) //indoorhumidity
Number   DIV_Wetterstation_feuchtigkeit_aussen "Luftfeuchtigkeit Außen [%d %%]" <humidity>(wifiWetterstation) //humidity
Number   DIV_Wetterstation_wind_geschwindigkeit "Windgeschwindigkeit [%.1f km/h]" <wind>(wifiWetterstation) //windspeedkmh
Number   DIV_Wetterstation_wind_boee_geschwindigkeit "Windgeschwindigkeit Böe [%.1f km/h]" <wind>(wifiWetterstation) //windgustkmh
Number   DIV_Wetterstation_wind_richtung "Windrichtung [%.0f %unit%]" <wind>(wifiWetterstation) //winddir
Number:Angle   DIV_Wetterstation_wind_richtung_umgewandelt "Windrichtung [%.0f %unit%]" <wind>(wifiWetterstation) //winddir
Number   DIV_Wetterstation_luftdruck_abs "Luftdruck abs. [%.0f hPa]" <pressure>(wifiWetterstation) //absbaromhpa
Number   DIV_Wetterstation_luftdruck "Luftdruck [%.0f hPa]" <pressure>(wifiWetterstation) //baromhpa
Number   DIV_Wetterstation_regen_aktuell "Regen aktuell [%.2f mm]" <rain>(wifiWetterstation) //rainmm
Number   DIV_Wetterstation_regen_tag "Regen akt. Tag [%.2f mm]" <rain>(wifiWetterstation) //dailyrainmm
Number   DIV_Wetterstation_regen_woche "Regen akt. Woche [%.0f mm]" <rain>(wifiWetterstation) //weeklyrainmm
Number   DIV_Wetterstation_regen_monat "Regen akt. Monat [%.0f mm]" <rain>(wifiWetterstation) //monthlyrainmm
Number   DIV_Wetterstation_regen_jahr "Regen akt. Jahr [%.0f mm]" <rain>(wifiWetterstation) //yearlyrainmm
Number   DIV_Wetterstation_sonne_einstrahlung "Sonneneinstrahlung [%.0f W/m²]" <sun>(wifiWetterstation) //solarradiation
Number   DIV_Wetterstation_sonne_uv "UV Index [%d]" <sun> (wifiWetterstation) //UV
String   DIV_Wetterstation_dateTime "Zeitpunkt Messung" <calendar> (wifiWetterstation)

// Wetterstation virtuelle ITEMS
DateTime DIV_Wetterstation_regen_aktuell_LastUpdate "Letzter Regen: [%1$td %1$tb at %1$tR]" <rain>
DateTime DIV_Wetterstation_wind_LastUpdate "Letzter Wind: [%1$td %1$tb at %1$tR]" <wind>
String DIV_Wetter_Windrichtung "Windrichtung [%s]" <wind>
String DIV_Wetter_Boenrichtung "Böenrichtung [%s]" <wind>
Number DIV_Wetter_Windstaerke_zahl "Windstärke [%d]" <wind>
String DIV_Wetter_Windstaerke_text "Windstärke [%s]" <wind>
DateTime Wetterstation_JSON_LastUpdate "Zeitpunkt Messung: [%1$td %1$tb at %1$tR]" <calendar>
.rules Datei erstellen / ergänzen:
rule "Letzte Regenmeldung"
when
Item DIV_Wetterstation_regen_aktuell changed
then 
    logInfo("wetter.rules", "Aktualisiere letzte Regenmeldung - Start")
    postUpdate(DIV_Wetterstation_regen_aktuell_LastUpdate, new DateTimeType())
    logInfo("wetter.rules", "Aktualisiere letzte Regenmeldung - Ende")
end

rule "Letzter Wind"
when
Item DIV_Wetterstation_wind_geschwindigkeit changed or
Item DIV_Wetterstation_wind_boee_geschwindigkeit changed
then 
    logInfo("wetter.rules", "Aktualisiere letzter Wind - Start")
    postUpdate(DIV_Wetterstation_wind_LastUpdate, new DateTimeType())
    logInfo("wetter.rules", "Aktualisiere letzter Wind - Ende")
end

rule "Letztes Updates von der Wetterstation"
when
Item Wetterstation_JSON changed
then 
    logInfo("wetter.rules", "Aktualisiere letztes Update der Wetterstation - Start")
    postUpdate(Wetterstation_JSON_LastUpdate, new DateTimeType())
    logInfo("wetter.rules", "Aktualisiere letztes Update der Wetterstation - Ende")
end

rule "Windrichtung"
 when
   Item DIV_Wetterstation_wind_richtung changed
then

if (DIV_Wetterstation_wind_richtung.state < 11.5 || DIV_Wetterstation_wind_richtung.state  >= 349)  DIV_Wetter_Windrichtung.postUpdate("Nord")
 else if (DIV_Wetterstation_wind_richtung.state >= 11.5 && DIV_Wetterstation_wind_richtung.state < 34) DIV_Wetter_Windrichtung.postUpdate("NordNordOst")
 else if (DIV_Wetterstation_wind_richtung.state >= 34 && DIV_Wetterstation_wind_richtung.state < 56.5) DIV_Wetter_Windrichtung.postUpdate("NordOst")
 else if (DIV_Wetterstation_wind_richtung.state >= 56.5 && DIV_Wetterstation_wind_richtung.state < 79) DIV_Wetter_Windrichtung.postUpdate("OstNordOst")
 else if (DIV_Wetterstation_wind_richtung.state >= 79 && DIV_Wetterstation_wind_richtung.state < 101.5) DIV_Wetter_Windrichtung.postUpdate("Ost")
 else if (DIV_Wetterstation_wind_richtung.state >= 101.5 && DIV_Wetterstation_wind_richtung.state < 103) DIV_Wetter_Windrichtung.postUpdate("OstSüdOst")
 else if (DIV_Wetterstation_wind_richtung.state >= 103 && DIV_Wetterstation_wind_richtung.state < 147.5) DIV_Wetter_Windrichtung.postUpdate("SüdOst")
 else if (DIV_Wetterstation_wind_richtung.state >= 147.5 && DIV_Wetterstation_wind_richtung.state < 169) DIV_Wetter_Windrichtung.postUpdate("SüdSüdOst")
 else if (DIV_Wetterstation_wind_richtung.state >= 169 && DIV_Wetterstation_wind_richtung.state < 191.5) DIV_Wetter_Windrichtung.postUpdate("Süd")
 else if (DIV_Wetterstation_wind_richtung.state >= 191.5 && DIV_Wetterstation_wind_richtung.state < 214) DIV_Wetter_Windrichtung.postUpdate("SüdSüdWest")
 else if (DIV_Wetterstation_wind_richtung.state >= 214 && DIV_Wetterstation_wind_richtung.state < 236.5) DIV_Wetter_Windrichtung.postUpdate("SüdWest")
 else if (DIV_Wetterstation_wind_richtung.state >= 236.5 && DIV_Wetterstation_wind_richtung.state < 259) DIV_Wetter_Windrichtung.postUpdate("WestSüdWest")
 else if (DIV_Wetterstation_wind_richtung.state >= 259 && DIV_Wetterstation_wind_richtung.state < 281.5) DIV_Wetter_Windrichtung.postUpdate("West")
 else if (DIV_Wetterstation_wind_richtung.state >= 281.5 && DIV_Wetterstation_wind_richtung.state < 304) DIV_Wetter_Windrichtung.postUpdate("WestNordWest")
 else if (DIV_Wetterstation_wind_richtung.state >= 304 && DIV_Wetterstation_wind_richtung.state < 326.5) DIV_Wetter_Windrichtung.postUpdate("NordWest")
 else if (DIV_Wetterstation_wind_richtung.state >= 326.5 && DIV_Wetterstation_wind_richtung.state < 349) DIV_Wetter_Windrichtung.postUpdate("NordNordWest")
end

rule "Windstärke umrechnen als Zahl und Text mit Quellwert in km/h"
when Item DIV_Wetterstation_wind_geschwindigkeit changed 
then
    if (DIV_Wetterstation_wind_geschwindigkeit.state < 1) {
        DIV_Wetter_Windstaerke_zahl.postUpdate(0)
        DIV_Wetter_Windstaerke_text.postUpdate("Windstille")
    } else if (DIV_Wetterstation_wind_geschwindigkeit.state <= 5) {
        DIV_Wetter_Windstaerke_zahl.postUpdate(1)
        DIV_Wetter_Windstaerke_text.postUpdate("Leiser Zug")
    } else if (DIV_Wetterstation_wind_geschwindigkeit.state <= 11) {
        DIV_Wetter_Windstaerke_zahl.postUpdate(2)
        DIV_Wetter_Windstaerke_text.postUpdate("Leichte Brise")
    } else if (DIV_Wetterstation_wind_geschwindigkeit.state <= 19) {
        DIV_Wetter_Windstaerke_zahl.postUpdate(3)
        DIV_Wetter_Windstaerke_text.postUpdate("Schwache Brise")
    } else if (DIV_Wetterstation_wind_geschwindigkeit.state <= 28) {
        DIV_Wetter_Windstaerke_zahl.postUpdate(4)
        DIV_Wetter_Windstaerke_text.postUpdate("Mäßige Brise")
    } else if (DIV_Wetterstation_wind_geschwindigkeit.state <= 38) {
        DIV_Wetter_Windstaerke_zahl.postUpdate(5)
        DIV_Wetter_Windstaerke_text.postUpdate("Frische Brise")
    } else if (DIV_Wetterstation_wind_geschwindigkeit.state <= 49) {
        DIV_Wetter_Windstaerke_zahl.postUpdate(6)
        DIV_Wetter_Windstaerke_text.postUpdate("Starker Wind")
    } else if (DIV_Wetterstation_wind_geschwindigkeit.state <= 61) {
        DIV_Wetter_Windstaerke_zahl.postUpdate(7)
        DIV_Wetter_Windstaerke_text.postUpdate("Steifer Wind")
    } else if (DIV_Wetterstation_wind_geschwindigkeit.state <= 74) {
        DIV_Wetter_Windstaerke_zahl.postUpdate(8)
        DIV_Wetter_Windstaerke_text.postUpdate("Stürmischer Wind")
    } else if (DIV_Wetterstation_wind_geschwindigkeit.state <= 88) {
        DIV_Wetter_Windstaerke_zahl.postUpdate(9)
        DIV_Wetter_Windstaerke_text.postUpdate("Sturm")
    } else if (DIV_Wetterstation_wind_geschwindigkeit.state <= 102) {
        DIV_Wetter_Windstaerke_zahl.postUpdate(10)
        DIV_Wetter_Windstaerke_text.postUpdate("Schwerer Sturm")
    } else if (DIV_Wetterstation_wind_geschwindigkeit.state <= 117) {
        DIV_Wetter_Windstaerke_zahl.postUpdate(11)
        DIV_Wetter_Windstaerke_text.postUpdate("Orkanartiger Sturm")
    } else {
        DIV_Wetter_Windstaerke_zahl.postUpdate(12)
        DIV_Wetter_Windstaerke_text.postUpdate("Orkan")
    } 
end

rule "WiFi Wetterstation Items"
    when 
        Item Wetterstation_JSON received update
    then
        logInfo("wetter.rules", "Daten der Wetterstation umnwandeln - Start")
        var jsonString = Wetterstation_JSON.state.toString()
        DIV_Wetterstation_temperatur_gefuehlt.postUpdate(transform("JSONPATH", "$.windchillc", jsonString))
        DIV_Wetterstation_temperatur_aussen.postUpdate(transform("JSONPATH", "$.tempc", jsonString))
        DIV_Wetterstation_temperatur_innen.postUpdate(transform("JSONPATH", "$.indoortempc", jsonString))
        DIV_Wetterstation_taupunkt.postUpdate(transform("JSONPATH", "$.dewptc", jsonString))
        DIV_Wetterstation_feuchtigkeit_innen.postUpdate(transform("JSONPATH", "$.indoorhumidity", jsonString))
        DIV_Wetterstation_feuchtigkeit_aussen.postUpdate(transform("JSONPATH", "$.humidity", jsonString))
        DIV_Wetterstation_wind_geschwindigkeit.postUpdate(transform("JSONPATH", "$.windspeedkmh", jsonString))
        DIV_Wetterstation_wind_boee_geschwindigkeit.postUpdate(transform("JSONPATH", "$.windgustkmh", jsonString))
        DIV_Wetterstation_wind_richtung.postUpdate(transform("JSONPATH", "$.winddir", jsonString))
        DIV_Wetterstation_wind_richtung_umgewandelt.postUpdate(transform("JSONPATH", "$.winddir", jsonString))
        DIV_Wetterstation_luftdruck_abs.postUpdate(transform("JSONPATH", "$.absbaromhpa", jsonString))
        DIV_Wetterstation_luftdruck.postUpdate(transform("JSONPATH", "$.baromhpa", jsonString))
        DIV_Wetterstation_regen_aktuell.postUpdate(transform("JSONPATH", "$.rainmm", jsonString))
        DIV_Wetterstation_regen_tag.postUpdate(transform("JSONPATH", "$.dailyrainmm", jsonString))
        DIV_Wetterstation_regen_woche.postUpdate(transform("JSONPATH", "$.weeklyrainmm", jsonString))
        DIV_Wetterstation_regen_monat.postUpdate(transform("JSONPATH", "$.monthlyrainmm", jsonString))
        DIV_Wetterstation_regen_jahr.postUpdate(transform("JSONPATH", "$.yearlyrainmm", jsonString))
        DIV_Wetterstation_sonne_einstrahlung.postUpdate(transform("JSONPATH", "$.solarradiation", jsonString))
        DIV_Wetterstation_sonne_uv.postUpdate(transform("JSONPATH", "$.UV", jsonString))
        DIV_Wetterstation_dateTime.postUpdate(transform("JSONPATH", "$.dateutc", jsonString))
        logInfo("wetter.rules", "Daten der Wetterstation umnwandeln - Ende")
    end
Die .sitemap Datei anpassen:
Text label="Wetterstation" icon="sun_clouds" {
	Frame label="WH4000SE Infos" {
		Default item=Wetterstation_JSON_LastUpdate
		Default item=DIV_Wetterstation_feuchtigkeit_innen
		Default item=DIV_Wetterstation_feuchtigkeit_aussen
		Default item=DIV_Wetterstation_luftdruck_abs
		Default item=DIV_Wetterstation_luftdruck
		Default item=DIV_Wetterstation_sonne_einstrahlung
 		Default item=DIV_Wetterstation_sonne_uv
	}
	Frame label="WH4000SE - Temperatur" {
		Default item=DIV_Wetterstation_temperatur_gefuehlt
		Default item=DIV_Wetterstation_temperatur_aussen
		Default item=DIV_Wetterstation_temperatur_innen
 		Default item=DIV_Wetterstation_taupunkt
	}
	Frame label="WH4000SE - Wind" {
		Default item=DIV_Wetterstation_wind_LastUpdate
		Default item=DIV_Wetterstation_wind_geschwindigkeit
		Default item=DIV_Wetter_Windstaerke_text
		Default item=DIV_Wetterstation_wind_boee_geschwindigkeit
		Default item=DIV_Wetterstation_wind_richtung_umgewandelt
		Default item=DIV_Wetter_Windrichtung
	}
	Frame label="WH4000SE - Regen" {
		Default item=DIV_Wetterstation_regen_aktuell_LastUpdate
		Default item=DIV_Wetterstation_regen_aktuell
		Default item=DIV_Wetterstation_regen_tag
		Default item=DIV_Wetterstation_regen_woche
		Default item=DIV_Wetterstation_regen_monat
		Default item=DIV_Wetterstation_regen_jahr
	}
}
Wetterstation anpassen:

Zu guter letzt muss in der „WS View“ App der Link bzw. die URL zum openHAB Server  (bei mir wäre das dann http://192.168.2.132/wetter/index.php) passend eingetragen werden: App öffnen > Menu > Device List > Wetterstation auswählen > Next > Next > Next > Next > und dort nun die Daten anpassen:

openhab WH4000SE

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert