Skip to content

Instantly share code, notes, and snippets.

@KorbinianP
Last active May 9, 2022 19:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KorbinianP/7436d3e0fc4c7ef257bf1924dc6af42f to your computer and use it in GitHub Desktop.
Save KorbinianP/7436d3e0fc4c7ef257bf1924dc6af42f to your computer and use it in GitHub Desktop.
An example of how I integrated the ELV ws980 Weatherstation to OpenHab 2.5. Somehow a "best of" of all the solutions on https://www.forwardme.de/2020/04/16/wetterstation-ws980-wifi-in-openhab-einbinden/. Some spice from me on top.
Frame label="Wetterstation WiFi"{
Default item=wetterstation_temperatur_gefuehlt
Default item=wetterstation_temperatur_aussen
Default item=wetterstation_temperatur_innen
Default item=wetterstation_taupunkt
Default item=wetterstation_feuchtigkeit_innen
Default item=wetterstation_feuchtigkeit_aussen
Default item=wetterstation_wind_geschwindigkeit
Default item=wetterstation_wind_boee_geschwindigkeit
Default item=wetterstation_wind_staerke_zahl
Default item=wetterstation_wind_staerke_text
Default item=wetterstation_wind_richtung
Default item=wetterstation_wind_richtung_text
Default item=wetterstation_luftdruck_abs
Default item=wetterstation_luftdruck
Default item=wetterstation_regen_aktuell
Default item=wetterstation_regen_tag
Default item=wetterstation_regen_woche
Default item=wetterstation_regen_monat
Default item=wetterstation_regen_jahr
Default item=wetterstation_sonne_einstrahlung
Default item=wetterstation_sonne_uv
}
<?php
/* Source: https://www.forwardme.de/2020/04/16/wetterstation-ws980-wifi-in-openhab-einbinden/
* Aufruf index.php mit Parameter ?read=1 gibt JSON zurück
*/
$filename_latest = 'data/latest.txt';
$restapi_url = 'http://192.168.178.71: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;
}
// Wetterstation WS980 wifi
String Wetterstation_JSON "Alle Werte der Wetterstation, codiert als JSON"
Group wifiWetterstation "Wetterstation WS980wifi" (store)
Number wetterstation_temperatur_gefuehlt "Gefühlte Temp. [%.1f °C]" <temperature>(wifiWetterstation) //windchillc
Number wetterstation_temperatur_aussen "Temp. außen [%.1f °C]" <temperature>(wifiWetterstation) //tempc
Number wetterstation_temperatur_innen "Temp. innen [%.1f °C]" <temperature>(wifiWetterstation) //indoortempc
Number wetterstation_taupunkt "Taupunkt [%.1f °C]" <temperature>(wifiWetterstation) //dewptc
Number wetterstation_feuchtigkeit_innen "Feuchtigkeit Innen [%d %%]" <humidity>(wifiWetterstation) //indoorhumidity
Number wetterstation_feuchtigkeit_aussen "Feuchtigkeit außen [%d %%]" <humidity>(wifiWetterstation) //humidity
Number wetterstation_wind_geschwindigkeit "Windgeschwindigkeit [%.1f km/h]" <wind>(wifiWetterstation) //windspeedkmh
Number wetterstation_wind_boee_geschwindigkeit "Windgeschwindigkeit Böe [%.1f km/h]" <wind>(wifiWetterstation) //windgustkmh
Number wetterstation_wind_richtung "Windrichtung [%d]" <wind>(wifiWetterstation) //winddir
Number wetterstation_luftdruck_abs "Luftdruck abs. [%.0f hPa]" <pressure>(wifiWetterstation) //absbaromhpa
Number wetterstation_luftdruck "Luftdruck [%.0f hPa]" <pressure>(wifiWetterstation) //baromhpa
Number wetterstation_regen_aktuell "Regen aktuell [%.2f mm]" <rain>(wifiWetterstation) //rainmm
Number wetterstation_regen_tag "Regen akt. Tag [%.2f mm]" <rain>(wifiWetterstation) //dailyrainmm
Number wetterstation_regen_woche "Regen akt. Woche [%.0f mm]" <rain>(wifiWetterstation) //weeklyrainmm
Number wetterstation_regen_monat "Regen akt. Monat [%.0f mm]" <rain>(wifiWetterstation) //monthlyrainmm
Number wetterstation_regen_jahr "Regen akt. Jahr [%.0f mm]" <rain>(wifiWetterstation) //yearlyrainmm
Number wetterstation_sonne_einstrahlung "Sonne akt. [%.0f w/m²]" <sun>(wifiWetterstation) //solarradiation
Number wetterstation_sonne_uv "UV [%d]" <sun_clouds>(wifiWetterstation) //UV
// Virtuelle items Wetterstation
String wetterstation_wind_richtung_text "Windrichtung [%s]" <wind>(wifiWetterstation)
Number wetterstation_wind_staerke_zahl "Windstärke [%d]" <wind>(wifiWetterstation)
String wetterstation_wind_staerke_text "Windstärke [%s]" <wind>(wifiWetterstation)
rule "WiFi Wetterstation"
when
Item Wetterstation_JSON received update
then
logInfo("Wetterstation", "Start")
var jsonString = Wetterstation_JSON.state.toString()
wetterstation_temperatur_gefuehlt.postUpdate(transform("JSONPATH", "$.windchillc", jsonString))
wetterstation_temperatur_aussen.postUpdate(transform("JSONPATH", "$.tempc", jsonString))
wetterstation_temperatur_innen.postUpdate(transform("JSONPATH", "$.indoortempc", jsonString))
wetterstation_taupunkt.postUpdate(transform("JSONPATH", "$.dewptc", jsonString))
wetterstation_feuchtigkeit_innen.postUpdate(transform("JSONPATH", "$.indoorhumidity", jsonString))
wetterstation_feuchtigkeit_aussen.postUpdate(transform("JSONPATH", "$.humidity", jsonString))
wetterstation_wind_geschwindigkeit.postUpdate(transform("JSONPATH", "$.windspeedkmh", jsonString))
wetterstation_wind_boee_geschwindigkeit.postUpdate(transform("JSONPATH", "$.windgustkmh", jsonString))
wetterstation_wind_richtung.postUpdate(transform("JSONPATH", "$.winddir", jsonString))
wetterstation_luftdruck_abs.postUpdate(transform("JSONPATH", "$.absbaromhpa", jsonString))
wetterstation_luftdruck.postUpdate(transform("JSONPATH", "$.baromhpa", jsonString))
wetterstation_regen_aktuell.postUpdate(transform("JSONPATH", "$.rainmm", jsonString))
wetterstation_regen_tag.postUpdate(transform("JSONPATH", "$.dailyrainmm", jsonString))
wetterstation_regen_woche.postUpdate(transform("JSONPATH", "$.weeklyrainmm", jsonString))
wetterstation_regen_monat.postUpdate(transform("JSONPATH", "$.monthlyrainmm", jsonString))
wetterstation_regen_jahr.postUpdate(transform("JSONPATH", "$.yearlyrainmm", jsonString))
wetterstation_sonne_einstrahlung.postUpdate(transform("JSONPATH", "$.solarradiation", jsonString))
wetterstation_sonne_uv.postUpdate(transform("JSONPATH", "$.UV", jsonString))
logInfo("Wetterstation", "Done")
end
rule "Windrichtung anpassen"
when Item wetterstation_wind_richtung changed
then
if ((wetterstation_wind_richtung.state <= 30) || (wetterstation_wind_richtung.state >= 330)) {
wetterstation_wind_richtung_text.postUpdate("N");
} else if ((wetterstation_wind_richtung.state > 30) && (wetterstation_wind_richtung.state < 60)) {
wetterstation_wind_richtung_text.postUpdate("NO");
} else if ((wetterstation_wind_richtung.state >= 60) && (wetterstation_wind_richtung.state <= 120)) {
wetterstation_wind_richtung_text.postUpdate("O");
} else if ((wetterstation_wind_richtung.state > 120) && (wetterstation_wind_richtung.state < 150)) {
wetterstation_wind_richtung_text.postUpdate("SO");
} else if ((wetterstation_wind_richtung.state >= 150) && (wetterstation_wind_richtung.state <= 210)) {
wetterstation_wind_richtung_text.postUpdate("S");
} else if ((wetterstation_wind_richtung.state > 210) && (wetterstation_wind_richtung.state < 240)) {
wetterstation_wind_richtung_text.postUpdate("SW");
} else if ((wetterstation_wind_richtung.state >= 240) && (wetterstation_wind_richtung.state <= 300)) {
wetterstation_wind_richtung_text.postUpdate("W");
} else if ((wetterstation_wind_richtung.state > 300) && (wetterstation_wind_richtung.state < 330)) {
wetterstation_wind_richtung_text.postUpdate("NW");
} else {
wetterstation_wind_richtung_text.postUpdate("FEHLER");
}
end
rule "Windstärke umrechnen als Zahl und Text mit Quellwert in km/h"
when Item wetterstation_wind_geschwindigkeit changed
then
if (wetterstation_wind_geschwindigkeit.state < 1) {
wetterstation_wind_staerke_zahl.postUpdate(0)
wetterstation_wind_staerke_text.postUpdate("Windstille")
} else if (wetterstation_wind_geschwindigkeit.state <= 5) {
wetterstation_wind_staerke_zahl.postUpdate(1)
wetterstation_wind_staerke_text.postUpdate("Leiser Zug")
} else if (wetterstation_wind_geschwindigkeit.state <= 11) {
wetterstation_wind_staerke_zahl.postUpdate(2)
wetterstation_wind_staerke_text.postUpdate("Leichte Brise")
} else if (wetterstation_wind_geschwindigkeit.state <= 19) {
wetterstation_wind_staerke_zahl.postUpdate(3)
wetterstation_wind_staerke_text.postUpdate("Schwache Brise")
} else if (wetterstation_wind_geschwindigkeit.state <= 28) {
wetterstation_wind_staerke_zahl.postUpdate(4)
wetterstation_wind_staerke_text.postUpdate("Mäßige Brise")
} else if (wetterstation_wind_geschwindigkeit.state <= 38) {
wetterstation_wind_staerke_zahl.postUpdate(5)
wetterstation_wind_staerke_text.postUpdate("Frische Brise")
} else if (wetterstation_wind_geschwindigkeit.state <= 49) {
wetterstation_wind_staerke_zahl.postUpdate(6)
wetterstation_wind_staerke_text.postUpdate("Starker Wind")
} else if (wetterstation_wind_geschwindigkeit.state <= 61) {
wetterstation_wind_staerke_zahl.postUpdate(7)
wetterstation_wind_staerke_text.postUpdate("Steifer Wind")
} else if (wetterstation_wind_geschwindigkeit.state <= 74) {
wetterstation_wind_staerke_zahl.postUpdate(8)
wetterstation_wind_staerke_text.postUpdate("Stürmischer Wind")
} else if (wetterstation_wind_geschwindigkeit.state <= 88) {
wetterstation_wind_staerke_zahl.postUpdate(9)
wetterstation_wind_staerke_text.postUpdate("Sturm")
} else if (wetterstation_wind_geschwindigkeit.state <= 102) {
wetterstation_wind_staerke_zahl.postUpdate(10)
wetterstation_wind_staerke_text.postUpdate("Schwerer Sturm")
} else if (wetterstation_wind_geschwindigkeit.state <= 117) {
wetterstation_wind_staerke_zahl.postUpdate(11)
wetterstation_wind_staerke_text.postUpdate("Orkanartiger Sturm")
} else {
wetterstation_wind_staerke_zahl.postUpdate(12)
wetterstation_wind_staerke_text.postUpdate("Orkan")
}
end
@Mario-75
Copy link

Very nice work and thanks to the original post as well. Your code works for OH3.2 as well.
Unfortunately, the wind directions are not right! Why would you give N, E… 60 deg but NE, SO… only 30deg. The segments need to have the same size.
Here my adapted code for 16 segment wind rose

rule "Windrichtung anpassen"
    when Item wetterstation_wind_richtung changed 
    then 
        val tmpInput = (wetterstation_wind_richtung.state as Number).intValue
        // 16-wind compass rose, each segment is 22.5 degree, add 1 to avoid 0 as North (-11.25 to 11.25 is north)
        var tmpcalc1 = ((tmpInput+11.25)/22.5)+1
        // change decimal number to integer
        var int tmpcalc2 = tmpcalc1.intValue
        switch(tmpcalc2){
            case 1:{ wetterstation_wind_richtung_neu.postUpdate("N") }
            case 2:{ wetterstation_wind_richtung_neu.postUpdate("NNO") }
            case 3:{ wetterstation_wind_richtung_neu.postUpdate("NO") }
            case 4:{ wetterstation_wind_richtung_neu.postUpdate("ONO") }
            case 5:{ wetterstation_wind_richtung_neu.postUpdate("O") }
            case 6:{ wetterstation_wind_richtung_neu.postUpdate("OSO") }
            case 7:{ wetterstation_wind_richtung_neu.postUpdate("SO") }
            case 8:{ wetterstation_wind_richtung_neu.postUpdate("SSO") }
            case 9:{ wetterstation_wind_richtung_neu.postUpdate("S") }
            case 10:{ wetterstation_wind_richtung_neu.postUpdate("SSW") }
            case 11:{ wetterstation_wind_richtung_neu.postUpdate("SW") }
            case 12:{ wetterstation_wind_richtung_neu.postUpdate("WSW") }
            case 13:{ wetterstation_wind_richtung_neu.postUpdate("W") }
            case 14:{ wetterstation_wind_richtung_neu.postUpdate("WNW") }
            case 15:{ wetterstation_wind_richtung_neu.postUpdate("NW") }
            case 16:{ wetterstation_wind_richtung_neu.postUpdate("NNW") }
            case 17:{ wetterstation_wind_richtung_neu.postUpdate("N") }
            default : { wetterstation_wind_richtung_neu.postUpdate("Fehler") }
        }
    end

The code in OH3.2 Rules ECMAScript looks even more simple, since you can use one list item with all directions in order N,NNO,NO...
Best regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment