Modul für DWD Open Data

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

Vorheriges Thema - Nächstes Thema

jensb

Auf GitHub gibt es eine Vorabversion des OpenData-Moduls, mit der man forecastResolution=1 ausprobieren kann. Damit bekommt man bei einigen Readings wirklich 24 Werte pro Tag. Bitte die Performance-Hinweise in der Modulhilfe beachten.

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

somansch

@mumpitzstuff,

danke für deine logproxy-Funktion  :).

Habe den Teil für max. Temp, min. Temp und Niederschlagsmenge verwendet. Jetzt fehlt noch ein Lösung für die jeweiligen Icons der Wetterlage für ein perfektes Meteogram mit dem Chart-widget im FTUI:

curt

Zitat von: mumpitzstuff am 19 Dezember 2018, 23:46:12
Das filelog device auf dem der Plot aufbaut, muss diese Attribute haben:

Das Device müsste in meinem Verständnis die Perl-Routine aufrufen. Ich weiß nicht, wie das geht.

Kannst Du bitte die komplette Sektion zeigen?
RPI 4 - Jeelink HomeMatic Z-Wave

mumpitzstuff

Ich habe mir vom DWD device ein filelog Device abgeleitet. Wenn man dieses dann öffnet, dann kann man dort ein SVG erstellen. Dieses SVG kann man unter edit files bearbeiten.

define FileLog_WETTER_DWD FileLog ./log/WETTER_DWD-%Y-%m.log WETTER_DWD

mumpitzstuff

Danke für den Hinweis. Habe bei Tn und Tx jeweils um (-6*3600) verschoben. Das mit den Stundenwerten probiere ich beizeiten aus und poste die Ergebnisse.

Das mit den Icons hätte ich auch gern mit Logproxy gemacht, nur leider wird das dort nicht unterstützt. Sieht aber echt super aus.

curt

Hmmm :(

Kannst Du Deinen aktuellen Stand bitte einfach mal komplett zeigen? Das würde sicher nicht nur mir helfen.
RPI 4 - Jeelink HomeMatic Z-Wave

mumpitzstuff

Was verstehst du unter komplett? Die komplette Definition vom dwd device, dem filelog device und den Inhalt der svg Datei? Das ist eigentlich schon sehr vollständig in meinem Post. Wo genau hängst du denn fest?

mumpitzstuff

Zitat von: somansch am 20 Dezember 2018, 23:25:36
@mumpitzstuff,

danke für deine logproxy-Funktion  :).

Habe den Teil für max. Temp, min. Temp und Niederschlagsmenge verwendet. Jetzt fehlt noch ein Lösung für die jeweiligen Icons der Wetterlage für ein perfektes Meteogram mit dem Chart-widget im FTUI:

Könntest du für die Icons nicht erst mal die Proplanta Icons für die jeweiligen Tage verwenden? Kann man in FTUI nicht Dinge aus 2 verschiedenen Devices mixen?

mumpitzstuff

forecastResolution kann man anscheinend mit dem Kommando bereits auf 1 setzen:

attr WETTER_DWD forecastResolution 1

jensb

#414
Hier noch ein paar Zusammenhänge für den Plot von @mumpitzstuff:

SVG fixedoffset = DWD_OpenData forecastDays
SVG fixedrange = (SVG fixedoffset + 1)  + "days"

Für Aggregatewerte wie die Regenmenge, die sich auf mehrere Stunden beziehen, sollte man den Messwert durch die Anzahl Stunden dividieren. Im Plot sieht man die Fläche und die muss die ursprüngliche Summe ergeben. Dann ist auch ein direkter Vergleich mit dem Regensensor plausibel.

Auf die Schnelle hilft dafür hinter der Zeile für SunD in der sub logProxy_dwd2Plot
$value = $value/6  if ('RR6c' eq $fcValue);
Ein weiterer Übergabeparameter für die sub wäre aber besser.

Da die sub automatisch die forecastResolution übernimmt, sollte man nur Aggregatewerte für die gleiche Zeitspanne verwenden. Will man das nicht, bietet es ich an, zusätzlich durch das (Miss-)Verhältnis zu dividieren, also bei forecastResolution=3h und Zeitspanne=6h noch einmal durch 2 dividieren.

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

somansch

Zitat von: mumpitzstuff am 21 Dezember 2018, 20:44:02
Könntest du für die Icons nicht erst mal die Proplanta Icons für die jeweiligen Tage verwenden? Kann man in FTUI nicht Dinge aus 2 verschiedenen Devices mixen?

Ja, jedoch sind das natürlich dann die Vorhersagesymbole von Proplanta und sie werden auch nicht auf der Linie mit der jeweiligen Temp. max. angezeigt:

mumpitzstuff

Ja gut. Aber erst mal besser als nix. Das Symbol ist sowieso extrem grob, das sollte in den meisten Fällen gleich sein.

mumpitzstuff

#417
So langsam wirds doch was. Hier sind jetzt meine kompletten Devices. Ich habe inzwischen 2 Plots erstellt, damit man das mal im direkten Vegleich sehen kann. im ersten DWD Plot sind die meisten Werte bezogen auf 3h und im zweiten auf 1h. Die Vorschläge von jensb sind aber noch nicht mit eingearbeitet, darüber muss ich noch ein wenig nachdenken.

1.) DWD Device (aktuell kann man forecastResolution 1 nur als Kommando setzen und nicht über die Oberfläche):
defmod WETTER_DWD DWD_OpenData
attr WETTER_DWD alertArea 808118011
attr WETTER_DWD event-on-change-reading .*
attr WETTER_DWD forecastProperties Tx,Tn,Tg,TTT,DD,FX1,N,Neff,RR1c,RR3c,RR6c,RRhc,RRL1c,Rh00,ww,SunD,SunD1,SunD3,RSunD,R101,R600
attr WETTER_DWD forecastResolution 1
attr WETTER_DWD forecastStation 10738
attr WETTER_DWD forecastWW2Text 1


2.) Logproxy Device:
defmod LOG_PROXY logProxy

3.) Filelog Device:
defmod FileLog_WETTER_DWD FileLog ./log/WETTER_DWD-%Y-%m.log WETTER_DWD

4.) Funktion in der myUtils.pm
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]+_".$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+)_.*/);
        my ($ao) = ($a =~ m/fc\d+_(\d+).*/);
        my ($bo) = ($b =~ m/fc\d+_(\d+).*/);
        $an <=> $bn or $ao <=> $bo 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+/)
      {
        $h = $1;
      }
    }
    else
    {
      $h = $fcHour;
    }

    $value = ReadingsVal($device, $reading, undef);
    if ($fcValue =~ /^SunD(\d+)/)
    {
      if (defined($1))
      {
        $value = (100 * $value) / ($1 * 3600);
      }
      else
      {
        $value = (100 * $value) / (12 * 3600);
      }
    }

    ($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);
}


5.) Im Filelog Device kann man auf "Create SVG Plot" klicken, dann wird eine SVG Datei erzeugt. In dieser Detei muss man den Inhalt komplett durch den folgenden ersetzen:

3h Daten:
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",(-6*3600))
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","Tn",$from,$to,0,"day",(-6*3600))
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","SunD3_",$from,$to,0,"day",(-1.5*3600))
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","RR3c_",$from,$to,0,"day",(-1.5*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 steps,\
     "<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


1h Daten:
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",(-6*3600))
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","Tn",$from,$to,0,"day",(-6*3600))
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","SunD1_",$from,$to,0,"day",(-0.5*3600))
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","RR1c_",$from,$to,0,"day",(-0.5*3600))
#LOG_PROXY Func:logProxy_dwd2Plot("WETTER_DWD","R101_",$from,$to,0,"day",(-0.5*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 steps,\
     "<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


Den stündlichen Wert für die Regenwahrscheinlichkeit gabs nur für Regenmengen > 0.1mm. Aus diesem Grund ist hier wahrscheinlich die Gesamtwahrscheinlichkeit tendenziell geringer.

curt

#418
@mumpitzstuff
Zitat von: mumpitzstuff am 21 Dezember 2018, 22:56:07
Hier sind jetzt meine kompletten Devices.

Sehr herzlichen Dank!
Jetzt tut sich was. Mir fehlte No. 2.

Zitat von: mumpitzstuff am 21 Dezember 2018, 22:56:07
1.) DWD Device (aktuell kann man forecastResolution 1 nur als Kommando setzen und nicht über die Oberfläche):

Kannst Du bitte erklären, wie man das konkret macht?

P.S: Ich lese gerade @jensb in #405: Vorabversion. Ok, verstanden.
RPI 4 - Jeelink HomeMatic Z-Wave

mumpitzstuff

Einfach #413 in diedie Fhem Kommandozeile eingeben, dann geht das auch schon ohne Vorabversion.