Modul für DWD Open Data

Begonnen von jensb, 21 Januar 2018, 14:38:48

Vorheriges Thema - Nächstes Thema

curt

Jetzt hast Du nun wieder mich verunsichert ...

fc0_SunD (Sonnenscheindauer Sekunden) oder fc0_Tx (Maximaltemperatur) beziehen sich auf welche 24 Stunden, welcher Tag? Und wann wird bei den beiden fc1 zu fc0?
RPI 4 - Jeelink HomeMatic Z-Wave

mumpitzstuff

Das Ganze ist mir ehrlich gesagt zu komplex bzw. zeitaufwendig, aber dafür kann ja niemand was, sondern lediglich DWD selbst. Ich müsste mir mühsamst separat für jedes Reading die Zeitpunkte zurecht fummeln, denn auch die anderen Werte beziehen sich auf die zurückliegenden Stunden. Alles sehr verwirrend und den Aufwand für mich nicht wert.

curt

Nun lauf mal nicht gleich weg.

Der DWD hat neben dem von Dir benannten Nachteil einen riesigen Vorteil: Während alle anderen Wettermodelle mit 10x10-Kilometer-Raster rechnen, hat der DWD das 1x1-Kilometer-Raster. Dies ind die präzisesten, die man für Deutschland haben kann.

Wir mühen uns ja alle (nochmal besonderen Dank an @jensb ), dass das sowohl als Modul als auch vias FTUI-weather-Widget handhabbar wird.
RPI 4 - Jeelink HomeMatic Z-Wave

jensb

Die zuletzt angesprochene Problematik mit der Vergleichbarkeit der Vorhersagewerte lässt sich im Normalfall mit genauem Lesen der Dokumentation in den Griff bekommen.

Der DWD meldet bei der Vorhersage z.B. keine standardisierten Werte für alle Stationen sondern so genau, wie es die lokale Messstation hergibt, und die ist je nach Standort nicht immer gleich ausgestattet, insbesondere da auch internationale Stationen dabei sind.

Zitatfc0_SunD (Sonnenscheindauer Sekunden) oder fc0_Tx (Maximaltemperatur) beziehen sich auf welche 24 Stunden, welcher Tag?
In der Modulhilfe steht dazu "day properties (typically for 06:00 station time, see raw data of station for time relation)". Mit "raw data" ist gemeint, dass man sich mal eine Datei vom Open Data Server manuell herunterlädt, auspackt und nachsieht, auf welchem Meldezeitpunkt sich der Wert tatsächlich bezieht. Das OpenData-Modul will dem Anwender bei den Tageswerten den Zugriff erleichtern und meldet den Wert nicht als Stundenwert, denn dann könnte sich der Stundenindex sporadisch ändern. Allerdings steht so die Meldezeit nicht zur Verfügung. Ansonsten die Antwort #390 noch mal in Ruhe lesen.

ZitatUnd wann wird bei den beiden fc1 zu fc0?
Um 00:00 werden alle fc0_* gelöscht und alle anderen um einen Tages-Index in Richtung 0 verschoben. Stehen neue Daten vom DWD zur Verfügung werden die rotierten Daten mit den neuen Daten überschrieben. Ansonsten fehlt nach dem Tageswechsel der letzte Tag bis wieder neue Daten eintreffen.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

frank

hallo jens,
ich verstehe curts problem so:

fc0_sunD ist einerseits ein vorhersagewert der heute ausgegeben wird, aber andererseits daten von gestern liefert.

das ist schon kurios, oder?
da wäre ja ein messwert von gestern genauer.
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

jensb

@mumpitzstuff

ZitatIch müsste mir mühsamst separat für jedes Reading die Zeitpunkte zurecht fummeln, denn auch die anderen Werte beziehen sich auf die zurückliegenden Stunden.
Je nachdem was du aus den Daten machen willst, wird sich das nicht vermeiden lassen. Dieses Problem stellt sich aber immer in der einen oder anderen Weise und ist meiner Meinung nach kein spezielles Feature des DWD.

Leichter wird es dann, wenn man alle Daten den gleichen Bezugszeitraum haben, wie man an Datendichte benötigt, also wenn man z.B. alle 3 Stunden Werte haben will und alle Summenwerte (wie z.B. die Niederschalgsmenge) auch über 3 Stunden gebildet werden.

Es gibt vom DWD auch noch sehr viele andere Datensätze, allerdings braucht man dann auch ein Stück mehr Rechenleistung und Algorithmik, um diese Rohdaten auszuwerten. Dann bist du aber nicht mehr auf Stationen beschränkt und kannst wahrscheinlich auch zeitlich eine höhere Auflösung erreichen. Diesen Weg hatte @betateilchen mal als Alternative zum alten DWD GDS-Dienst angedeutet.

Aktuell ist das OpenData-Modul bei der Vorhersage künstlich in der Zeitauflösung beschränkt. Wenn es hilft, kann ich diese Beschränkung entfernen und dann 1, 2, 3, 4, 6, 8 und 12 Stunden zur Auswahl anbieten. Dann hat man mit forecastResolution=1h alles zur Verfügung was der DWD für die Station anbietet.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

curt

Zitat von: frank am 19 Dezember 2018, 20:35:16
hallo jens,
ich verstehe curts problem so:
fc0_sunD ist einerseits ein vorhersagewert der heute ausgegeben wird, aber andererseits daten von gestern liefert.

Ich bin mir eben nicht sicher, ob das stimmt. fc0_date sagt aktuell 2018-12-19. Also heute. Daher ist logisch und erwartbar, dass fc0_sunD eben die heutige Sonnenscheindauer und fc0_Tx die heutige Maximaltemperatur ist.

Wenn dem nicht so wäre, wäre die Datumsangabe völlig sinnfreier Mumpitz.
RPI 4 - Jeelink HomeMatic Z-Wave

jensb

@frank + @curt

Zitatfc0_sunD ist einerseits ein vorhersagewert der heute ausgegeben wird, aber andererseits daten von gestern liefert.
ZitatDaher ist logisch und erwartbar, dass fc0_sunD eben die heutige Sonnenscheindauer und fc0_Tx die heutige Maximaltemperatur ist.

Ich verstehe den scheinbaren Widerspruch, aber das ist meiner Meinung nach ein Frage der Perspektive.

Der DWD bietet die Messwerte in Tabellenform an (es ist nicht wirklich eine Tabelle aber es ist so besser vorzustellen). Die Zeilen sind die Stunden und die Spalten sind die Messwerte. Am Ende der Tabelle wird irgendwann der nächste Vorhersagetag angehängt und so wie die Zeit vergeht, werden die vorderen Zeilen der Tabelle von der Gegenwart eingeholt. Wenn ich im OpenData-Modul die veralteten Readings löschen würde, würden sich wahrscheinlich viele Anwender beschweren. Deshalb kommt man nicht umhin, die Uhrzeit bei der Auswertung mit einzubeziehen.

Das OpenData-Modul ändert die Tabelle vom DWD nicht, sondern wandelt sie in Readings um. Ein Wert mit 24h-Bezug der für heute 06:00 geliefert wird, bezieht sich dann immer noch auf die 24h davor, aber immerhin noch auf 6h von heute, die allerdings um 07:00 bereits vorbei sind.

Theoretisch könnte man im OpenData-Modul diesen Effekt minimieren, indem man die Daten verschiebt. Aber das ist wie gesagt kein leichtes Unterfangen, da es sehr viele Stationen gibt und nicht alle gleich sind. Eine Alternative wäre eine konfigurierbare Verschiebung pro Reading, die aber wahrscheinlich auch nicht jeder Anwender in den Griff bekommt.

Wenn man aber weiß, dass die Sonnenscheindauer von heute im Reading von morgen steckt, dann ist das doch nicht schwierig zu verarbeiten.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

jensb

Hier noch die Rückmeldung zu Tn und Tx. Die Modulhilfe sagt dazu:

ZitatTn [°C] - minimum temperature of previous 24 hours (typically for 06:00 station time ...)
Tn bezieht sich also bei den meisten Stationen auf den laufenden Tag bis 06:00. Eine Ausnahme wäre ein sehr kalter Vortag, gefolgt von einer heißen Nacht. Tn ist in einigen Fällen nicht die kälteste Temperatur des laufenden Tages, da die z.T. nach 06:00 noch weiter fällt, vor allem im Winter.

ZitatTx [°C] - maximum temperature of previous 24 hours (typically for 18:00 station time)
Tx bezieht sich also bei den meisten Stationen auf den laufenden Tag bis 18:00. Eine Ausnahme wäre ein sehr heißer Abend, gefolgt von einem sehr kalten Tag. Tx ist in einigen Fällen nicht die heißeste Temperatur des laufenden Tages, da die im Sommer z.T. nach 18:00 noch etwas steigen kann.

Wer andere Zeitbezüge benötigt, könnte auf Basis der Stundenwerte Minimum und Maximum selbst bestimmen.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

frank

ZitatWenn man aber weiß, dass die Sonnenscheindauer von heute im Reading von morgen steckt, dann ist das doch nicht schwierig zu verarbeiten.
finde ich auch.

bei fc0_day habe ich mich nur gefragt, ob der dwd am morgen des aktuellen tages wirklich nochmal das rechenzentrum eingeschaltet hat, um diesen wert aufwendig neu zu berechnen. inklusive den fehlern, die eine vorhersage mit sich bringt. das fände ich kurios.

oder ist es einfach nur durch verschieben vom vortag entstanden? oder ist es vielleicht sogar der tatsächliche messwert von gestern.
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

jensb

Zitatbei fc0_day habe ich mich nur gefragt, ob der dwd am morgen des aktuellen tages wirklich nochmal das rechenzentrum eingeschaltet hat, um diesen wert aufwendig neu zu berechnen. inklusive den fehlern, die eine vorhersage mit sich bringt. das fände ich kurios.
oder ist es einfach nur durch verschieben vom vortag entstanden? oder ist es vielleicht sogar der tatsächliche messwert von gestern.
Ich vermute, dass der DWD die Daten bei jeder Aktualisierung neu berechnet hat. Die meterologische Simulation betrachtet mehr als nur eine Station und ihr ist es egal wie spät oder hell es irgendwo ist.

Das macht zwar für die Sonnenscheindauer nach Sonnenuntergang scheinbar keinen Sinn, aber dann doch wieder, wenn die Sonne vor 06:00 aufgeht.

Wenn man die Zeitstempel an den Readings beobachtet, sieht man, dass bestimmte Readings für heute ab einer bestimmten Uhrzeit nicht mehr aktualisiert werden.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

frank

ZitatDas macht zwar für die Sonnenscheindauer nach Sonnenuntergang scheinbar keinen Sinn, aber dann doch wieder, wenn die Sonne vor 06:00 aufgeht.
bei sunD steht wirklich "yesterday" als zeitbezug,  nicht die letzten 24std. dafür gibt es noch andere werte.
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

mumpitzstuff

#402
Mein bisherigen Ergebnisse:

Funktion in myUtils eintragen:
sub logProxy_dwd2Plot($$$$;$$$)
{
  my ($device, $fcValue, $from, $to, $fcHour, $expMode, $shiftTime) = @_;
  my $regex;
  my @rl;

  return undef if(!$device);

  if ($fcValue =~ s/_$//)
  {
    $regex = "^fc[\\d]+_[\\d]{1}_".$fcValue."\$";
  }
  else
  {
    $regex = "^fc[\\d]+_".$fcValue."\$";
  }

  $fcHour = 12 if(!defined($fcHour));
  $expMode = "point" if(!defined($expMode));
  #Log3 undef,2, "Regex: ".$regex;

  # ermitteln aller relevanten Readings
  if ( defined($defs{$device}) )
  {
    if ( $defs{$device}{TYPE} eq "DWD_OpenData" )
    {
      @rl = sort
      {
        my ($an) = ($a =~ m/fc(\d+)_.*/);
        my ($bn) = ($b =~ m/fc(\d+)_.*/);
        $an <=> $bn or $a cmp $b;
      } ( grep /${regex}/,keys %{$defs{$device}{READINGS}} );
      #Log3 undef,2, Dumper(@rl);
      return undef if ( !@rl );
    }
    else
    {
      Log3 undef, 2, "logProxy_dwd2Plot: $device is not a DWD_OpenData device";
      return undef;
    }
  }
  #Log3 undef,2, Dumper(@rl);

  my $fromsec = SVG_time_to_sec($from);
  my $tosec   = SVG_time_to_sec($to);
  my $sec = $fromsec;
  my ($h, $hp, $fcDay, $mday, $mon, $year);
  my $timestamp;

  my $reading;
  my $value;
  my $prev_value;
  my $min = 999999;
  my $max = -999999;
  my $ret = "";

  # while not end of plot range reached
  while (($sec < $tosec) && @rl)
  {
    #remember previous value for start of plot range
    $prev_value = $value;

    $reading = shift @rl;
    ($fcDay) = $reading =~ m/^fc(\d+).*/;
    ($hp) = $reading =~ m/^fc[\d]_(\d).*/;
    #Log 1, "hp: ".$hp;

    if ($hp)
    {
      $h = ReadingsVal($device, "fc".$fcDay."_".$hp."_time", $fcHour);
      if ($h =~ m/^(\d\d):\d\d/)
      {
        $h = $1;
      }
    }
    else
    {
      $h = $fcHour;
    }

    $value = ReadingsVal($device, $reading, undef);
    $value = (100 * $value) / (12 * 3600) if ('SunD' eq $fcValue);

    ($year, $mon, $mday) = split('\-',ReadingsVal($device, "fc".$fcDay."_date",undef));
    $timestamp = sprintf("%04d-%02d-%02d_%02d:%02d:%02d", $year, $mon, $mday, $h, 0, 0);
    $sec = SVG_time_to_sec($timestamp);
    if (defined($shiftTime))
    {
      $sec += $shiftTime;
      $timestamp = logProxy_shiftTime($timestamp, $shiftTime);
    }

    # skip all values before start of plot range
    next if ( $sec < $fromsec );

    # add first value at start of plot range
    if ( !$ret && $prev_value )
    {
      $min = $prev_value if ( $prev_value < $min );
      $max = $prev_value if ( $prev_value > $max );
      $ret .= "$from $prev_value\n";
    }

    # done if after end of plot range
    last if ($sec > $tosec);

    $min = $value if ( $value < $min );
    $max = $value if ( $value > $max );

    # add actual control point
    $ret .= "$timestamp $value\n";

    #Log 1, "$timestamp $value <<< $reading";
  }

  if (($sec < $tosec) && !@rl && ($expMode eq "day"))
  {
    $timestamp = sprintf("%04d-%02d-%02d_%02d:%02d:%02d", $year, $mon, $mday, 23, 59, 59);
    $_ = SVG_time_to_sec($timestamp);
    if (defined($shiftTime))
    {
      $_ += $shiftTime;
      $timestamp = logProxy_shiftTime($timestamp, $shiftTime);
    }

    if ($_ < $tosec)
    {
      $ret .= "$timestamp $value\n";
    }
    else
    {
      $ret .= "$to $value\n";
    }
  }
  elsif (($sec > $tosec) && ($expMode eq "day"))
  {
    $value = $prev_value + ($value - $prev_value) * (86400 + ($tosec - $sec)) / 86400;
    $ret .= "$to $value\n";
  }

  return ($ret, $min, $max, $prev_value);
}


Plot anlegen (LOG_PROXY durch eigenes LogProxy device ersetzen und WETTER_DWD durch das eigene DWD device):
set terminal png transparent size <SIZE> crop
set output '<OUT>.png'
set xdata time
set timefmt "%Y-%m-%d_%H:%M:%S"
set xlabel " "
set title '<TL>'
set ytics
set y2tics
set grid ytics
set ylabel "rain mm"
set y2label "temperature"
set y3label "cloud / chOfRain / sun (rel) %"
set y3range [0:100]

#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","TTT_",$from,$to,0,"day")
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","Tx",$from,$to,0,"day")
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","Tn",$from,$to,0,"day")
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","SunD",$from,$to,0,"day",(-36*3600))
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","RR6c_",$from,$to,0,"day",(-3*3600))
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","R600_",$from,$to,0,"day",(-3*3600))
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","Neff_",$from,$to,0,"day")
#LOG_PROXY ConstY:0
#LOG_PROXY ConstY:0

plot "<IN>" using 1:2 axes x1y2 title 'fc_temp' ls l0 lw 2 with quadraticSmooth,\
     "<IN>" using 1:2 axes x1y2 title 'fc_tempMax' ls l0dot lw 2 with quadraticSmooth,\
     "<IN>" using 1:2 axes x1y2 title 'fc_tempMin' ls l6 lw 2 with quadraticSmooth,\
     "<IN>" using 1:2 axes x1y3 title 'fc_sun' ls l4fill lw 1 with bars,\
     "<IN>" using 1:2 axes x1y1 title 'fc_rain' ls l2fill lw 1 with steps,\
     "<IN>" using 1:2 axes x1y3 title 'fc_chOfRain' ls l5fill lw 1 with quadraticSmooth,\
     "<IN>" using 1:2 axes x1y3 title 'fc_cloud' ls l6fill lw 1 with quadraticSmooth,\     
     "<IN>" using 1:2 axes x1y3 notitle ls l4fill lw 1 with lines,\
     "<IN>" using 1:2 axes x1y2 notitle ls l2 lw 2 with lines

Anstatt Neff kann man auf N verwenden und anstatt SunD auch RSunD (braucht dann nicht umgerechnet zu werden).

Das filelog device auf dem der Plot aufbaut, muss diese Attribute haben:

attr SVG_FileLog_WETTER_DWD_1 fixedoffset 6
attr SVG_FileLog_WETTER_DWD_1 fixedrange 7days
attr SVG_FileLog_WETTER_DWD_1 nrAxis 1,2


Bei DWD OpenData habe ich diese Attribute gesetzt:

attr WETTER_DWD forecastProperties Tx,Tn,Tg,TTT,DD,FX1,N,Neff,RR6c,RRhc,Rh00,ww,SunD,RSunD,R600
attr WETTER_DWD forecastResolution 3

jensb

@mumpitzstuff
Das ist schon sehr interessant. Bilder sagen wie so oft mehr als Worte.

Auf den ersten Blick wirkt der Plot für den DWD sehr "weich" im Vergleich zu Proplanta. Das liegt wahrscheinlich am 3h-Raster. Ich werde auf jeden Fall die 1h-Auflösung in der nächsten Version verfügbar machen. Dann dürfe auch beim DWD mehr Differenzierung sichtbar werden. Es gibt mehrere R1xx Werte für den Niederschlag und SunD1 für die Sonne, die dann in Frage kommen.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

jensb

@frank
Zitatbei sunD steht wirklich "yesterday" als zeitbezug ...
Danke für den Hinweis. Der Text aus der Modulhilfe stammt z.T. noch aus der Beschreibung der nicht mehr verfügbaren CSV-Daten vom DWD. Habe den ganzen Block noch mal kontrolliert. Die Min-/Max-Temperaturen sind übrigens nur für die letzten 12 Stunden. Die neue Version sieht nun so aus:

day properties (typically for 06:00 station time, see raw data of station for time relation)
             <li>date           - date based on the timezone attribute</li>
             <li>weekday    - abbreviated weekday based on the timezone attribute in the language of your FHEM system</li>
             <li>Tn [°C]       - minimum temperature of previous 12 hours</li>
             <li>Tx [°C]       - maximum temperature of previous 12 hours (typically at 18:00 station time)</li>
             <li>Tm [°C]      - average temperature of previous 24 hours</li>
             <li>Tg [°C]       - minimum temperature 5 cm above ground of previous 12 hours</li>
             <li>PEvap [kg/m2] - evapotranspiration of previous 24 hours</li>
             <li>SunD [ s]    - total sunshine duration of previous day</li>

Die Beschreibung des DWD für PEvap "Potential evapotranspiration within the last hour" kann nicht stimmen, da es nur 1 Wert pro Tag gibt.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb