Tägliche Regenmenge aus DWD-Radolan Daten einlesen

Begonnen von alkazaa, 12 August 2023, 21:12:09

Vorheriges Thema - Nächstes Thema

JoWiemann

Zitat von: romakrau am 25 August 2023, 09:08:01Hallo zusammen,
ich habe auch versucht das Modul zu definíeren und erhalte bei dem Versuch des Updates folgende Fehlermeldung:

Can't locate object method "gunzip" via package "Net::FTP::I" at ./FHEM/98_CDCOpenData.pm line 511.
2023.08.25 09:04:59 1: [Regenmenge | Readout_Aborted.678] - Error: Timeout when reading DWD data.

Gunzip ist in der Version
gunzip (gzip) 1.10
Copyright (C) 2007, 2011-2018 Free Software Foundation, Inc.
installiert.

Hallo Roman,

mach bitte einmal ein "reload 98_CDCOpenData.pm" in der Fhem Web Kommandozeile. Ich habe auch ab und zu die Fehlermeldung, die dann noch einem reload weg ist. Habe aber im Moment keinen Ansatz, woran das liegen kann.

Grüße Jörg
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

romakrau

Hallo Jörg,
Ich habe die letzte Version von Franz genommen.
Gruss Roman

alkazaa

Zitat von: romakrau am 25 August 2023, 09:08:01... Can't locate object method "gunzip" via package "Net::FTP::I" at ./FHEM/98_CDCOpenData.pm line 511. ...
Ich hatte das gunzip-Problem auch schon (allerdings auch auf nicht ganz reproduzierbare Weise) in meiner 99_myDWDUtils.pm Ur-Version. In den 98_CDCOpenData.pm Versionen ist es mir bisher nicht untergekommen.
"Geheilt" habe ich es in der 99_myDWDUtils.pm mit der Zeile
use IO::Uncompress::Gunzip qw(gunzip);einem Hinweis hier folgend.
ZitatGunzip ist in der Version
gunzip (gzip) 1.10
Copyright (C) 2007, 2011-2018 Free Software Foundation, Inc.
installiert.
Das kriege ich auch auf der Raspbian Kommadozeile. Das Betriebssystem-gunzip hat anscheinend mit dem perl-gunzip nichts zu tun.

ZitatDie Tagesmenge enthält den Fehler das mit einem GMT+2 die Sommerzeit angenommen wird. Es sollte daher die reale Zeit genommen werden, Kennung 22:50:00
Das versteh ich jetzt nicht: Wir haben doch jetzt in der Tat die MESZ Sommerzeit, mit MESZ=GMT+2. In London ist jetzt BST (British summer time), mit BST=GMT+1 (=MESZ-1).
Oder was seh ich da falsch?

Beste Grüße
Franz

romakrau

Hallo Franz,

die Änderung kann ich jetzt nicht durchführen da ich nicht zu Hause bin. Das mit der Zeit ist immer wieder verwirrend.
21:50 GMT = 22:50 D-Realzeit = 23:50 MESZ
22:50 GMT = 23:50 D-Realzeit = 00:50 MESZ
Die Zeitangabe der Datei ist in GMT?!
Ansonsten muss du den Code immer wieder zur Zeitumstellung ändern.
Gruss Roman

alkazaa

#34
Zitat von: romakrau am 25 August 2023, 15:58:34Hallo Franz,

die Änderung kann ich jetzt nicht durchführen da ich nicht zu Hause bin. Das mit der Zeit ist immer wieder verwirrend.
21:50 GMT = 22:50 D-Realzeit = 23:50 MESZ
22:50 GMT = 23:50 D-Realzeit = 00:50 MESZ
Die Zeitangabe der Datei ist in GMT?!
Ansonsten muss du den Code immer wieder zur Zeitumstellung ändern.
Gruss Roman
Die Zeitangaben der Radolan Dateien sind im UTC (früher GMT genannt), siehe diese Dokumentation.

Die Zeitumrechnungen in Perl haben mich an die Grenzen meines Verstandes gebracht (und ich bin nicht sicher, auf welche Seite der Grenze).
Daher bin ich auf das DateTime package verfallen, das angeblich die Sommerzeitprobleme sicher beherrscht.
Auf Anraten von rudolfkoenig weiter oben in diesem thread habe ich dann aber die DateTime Funktionen durch generische Perl Funktionen ersetzt, allerdings ohne die wirklich verstanden zu haben. Wie die Generika mit der Sommerzeit umgehen, muss ich noch rausfinden.
Als (abschreckendes?) Beispiel hier mal die Umrechnung der UTC-Zeitangabe aus der Radolan-Datei ($filetime) in einen FHEM-kompatiblen timestamp,
a) mit DateTime Funktionen:
$filetime->set_time_zone('Europe/Berlin')->strftime("%Y-%m-%d %H:%M:%S") b) mit generischen Perl Funktionen (so wie ich sie mir gebastelt habe, geht vermutlich/hoffentlich eleganter:
strftime("%Y-%m-%d %H:%M:%S",localtime($filetime+timelocal(localtime)-timelocal(gmtime)))
Z.Zt. jedenfalls liefert timelocal(localtime)-timelocal(gmtime) den Wert 7200, und ich hoffe, dass es ab 30.Oktober wieder 3600 liefert

JoWiemann

Hallo Franz,

wenn man sich in die Materie reinknien möchte, kann man das machen. DateTime ist zwar schwergewichtig, man kann aber auch nur Teile davon laden. In Fhem nutzen drei Module DateTime.

Du kannst Dir aber auch mal die Funktion, die Rudi bereit stellt ansehen. Vielleicht reichen ja auch die aus.

Grüße Jörg
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

rudolfkoenig

ZitatDie Zeitumrechnungen in Perl haben mich an die Grenzen meines Verstandes gebracht (und ich bin nicht sicher, auf welche Seite der Grenze).
Das gleiche Gefuehl habe ich auch beim betrachten der Zeitumrechnungen im Modul :)

Wo kommt timelocal her?
Ich vermute, dass es das Gegenteil von localtime ist, damit waere  timelocal(localtime) eine langsame Alternative zu time, da localtime ein "shortcut" fuer localtime(time) ist.

Die DateTime Konvertierung von gmt mit "Europe/Berlin" ist nur in Europa richtig, die andere Version ist besser.
Verwirrend ist mAn $filetime als Sekunden seit 1970 minus aktuellen, Sommerzeit abhaengigen UTC Offset zu speichern mit:
  $filetime = timelocal(0,$5,$4,$3,$2-1,$1+2000);
Ich wuerde stattdessen
  $filetime = fhemTimeGm(0,$5,$4,$3,$2-1,$1+100)
nehmen. Diesen Wert kann man mit
  strftime("%Y-%m-%d %H:%M:%S",localtime($filetime))
ausgeben.

alkazaa

Zitat von: rudolfkoenig am 25 August 2023, 20:47:56
ZitatDie Zeitumrechnungen in Perl haben mich an die Grenzen meines Verstandes gebracht (und ich bin nicht sicher, auf welche Seite der Grenze).
Das gleiche Gefuehl habe ich auch beim betrachten der Zeitumrechnungen im Modul :)

Wo kommt timelocal her?
Ich vermute, dass es das Gegenteil von localtime ist, damit waere  timelocal(localtime) eine langsame Alternative zu time, da localtime ein "shortcut" fuer localtime(time) ist.
Da bin ich wohl paarmal falsch abgebogen...

ZitatDie DateTime Konvertierung von gmt mit "Europe/Berlin" ist nur in Europa richtig, die andere Version ist besser.
Verwirrend ist mAn $filetime als Sekunden seit 1970 minus aktuellen, Sommerzeit abhaengigen UTC Offset zu speichern mit:
  $filetime = timelocal(0,$5,$4,$3,$2-1,$1+2000);
Ich wuerde stattdessen
  $filetime = fhemTimeGm(0,$5,$4,$3,$2-1,$1+100)
nehmen. Diesen Wert kann man mit
  strftime("%Y-%m-%d %H:%M:%S",localtime($filetime))
ausgeben.
OK, das hab ich jetzt so geändert. Die aktualisierte "DateTime'-freie Version ist im Anhang.

@Jörg/JoWiemann:
Danke nochmal für die tolle Umsetzung ins Modul!
Darüber hinaus: Ich hab gerade eine weitere subroutine 'rain_since_midnight' in Arbeit. Was sie tut, sagt der Name. Sie wertet dafür die 'hourly' Daten vom Server aus.
Falls Interesse besteht (stille Beobachter: bitte melden) schlage ich vor, dass beim 'set update' beide readings aktualisiert werden, amount-of-rain und rain-since midnight.

Ich selbst hätte noch den Wunsch (wäre aber nur das Sahnehäubchen), den verschiedenen locations einen sprechenderen Namen zu geben. Die Attribut-Definition könnte dann etwa so aussehen:
locations <ADorf:latitude,longitude> Bdorf:latitude,longitude .... Natürlich nur, wenn's nicht zuviel Aufwand ist.

Und nochwas: Ginge es, die amount-of-rain-time gleich als timestamp zu amount-of-rain hinzuzufügen. aber vielleicht läuft das irgendeiner internen FHEM Logik zuwider? Event-Generierung oder so?

Beste Grüße
Franz

JoWiemann

Zitat von: alkazaa am 26 August 2023, 16:30:18Darüber hinaus: Ich hab gerade eine weitere subroutine 'rain_since_midnight' in Arbeit. Was sie tut, sagt der Name. Sie wertet dafür die 'hourly' Daten vom Server aus.
Falls Interesse besteht (stille Beobachter: bitte melden) schlage ich vor, dass beim 'set update' beide readings aktualisiert werden, amount-of-rain und rain-since midnight.

Für mich gekauft.

Zitat von: alkazaa am 26 August 2023, 16:30:18Ich selbst hätte noch den Wunsch (wäre aber nur das Sahnehäubchen), den verschiedenen locations einen sprechenderen Namen zu geben. Die Attribut-Definition könnte dann etwa so aussehen:
locations <ADorf:latitude,longitude> Bdorf:latitude,longitude .... Natürlich nur, wenn's nicht zuviel Aufwand ist.

Nehme ich auf die ToDo Liste

Zitat von: alkazaa am 26 August 2023, 16:30:18Und nochwas: Ginge es, die amount-of-rain-time gleich als timestamp zu amount-of-rain hinzuzufügen. aber vielleicht läuft das irgendeiner internen FHEM Logik zuwider? Event-Generierung oder so?

Hm, dass ist eher eine philosophische Frage. Ich persönlich versuche die Readings vom Namen her einfach zu halten, um weitere Auswertungen nicht zu kompliziert werden zu lassen. Ich glaube ich lasse dem Benutzer die Wahl un mache das über ein Attribut auswählbar.

Wir ein bisschen dauern, da diese Woche echt voll ist.

Grüße Jörg
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

romakrau

Wollte nur eben mitteilen das Daten geladen werden. Mal schauen ob sich mit Hilfe des Statistiks Modul eine Aussage über einen Zeitraum von n-Tagen bauen lässt.

JoWiemann

Hallo,

anbei eine neue Beta, basierend auf den letzten Änderungen von Franz.

Sowohl bei der Definition, als auch beim Attribut locations kann, getrennt durch Doppelpunkt, vor die Geowerte ein Name gesetzt werden.

Mit gesetztem Attribut datetimeInReadingName wird der Reading Name um den Zeitpunkt ergänzt. Default ist nicht gesetzt.

Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

romakrau

Hallo,
ein Nichtsetzen des Namen führt wohl zu einer Fehlermeldung. Meine Geo-Daten beziehe ich aus "global".
Gruß
Roman
Use of uninitialized value $geoRef in concatenation (.) or string at ./FHEM/98_CDCOpenData.pm line 518.
Use of uninitialized value $geoRef in split at ./FHEM/98_CDCOpenData.pm line 527.

JoWiemann

Zitat von: romakrau am 29 August 2023, 10:30:54Hallo,
ein Nichtsetzen des Namen führt wohl zu einer Fehlermeldung. Meine Geo-Daten beziehe ich aus "global".
Gruß
Roman
Use of uninitialized value $geoRef in concatenation (.) or string at ./FHEM/98_CDCOpenData.pm line 518.
Use of uninitialized value $geoRef in split at ./FHEM/98_CDCOpenData.pm line 527.


Hallo Roman,

hast Du nur ein reload gemacht. Wenn ja, dann dürfte das Internal LOCATION nicht vorhanden sein und es entsteht Dein Fehler. Entweder FHEM neu starten oder das Device mit defmod <name> CDCOpenData erneuern.

Grüße Jörg
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

alkazaa

#43
Danke Jörg!
Bei mir läuft es wie gewünscht. Ich habe allerdings einen FHEM-restart gemacht, damit loc0 durch Home ersetzt wurde.

In der Anwendung mache ich das allerdings nach wie vor so, dass ich meinem vorhanden Weather-device namens 'Wetter' die Werte einmal pro Nacht mit einem 'at' 'unterschiebe':
defmod Get_Regenmenge_gestern at *01:35 {\
fhem "setreading Wetter ".ReadingsVal("myCDC","Home-amount-of-rain-time",0)." Regen_gestern ".ReadingsVal("myCDC","Home-amount-of-rain",-1);;\
fhem "setreading Wetter ".ReadingsVal("myCDC","ADorf-amount-of-rain-time",0)." Regen_gestern_ADorf ".ReadingsVal("myCDC","ADorf-amount-of-rain",-1);;\
fhem "setreading Wetter ".ReadingsVal("myCDC","BDorf-amount-of-rain-time",0)." Regen_gestern_BDorf ".ReadingsVal("myCDC","BDorf-amount-of-rain",-1)}
Diese Werte wandern dann in meine dblog-Datenbank.

Ich habe auch gesehen, dass Du ein Attribut numberOfDays vorgesehen hast. Ich hatte mir bereits für einen ähnlichen Zweck einen 'one-liner' für die FHEM-Kommandozeile gebastelt, der mir für ein gewünschtes Datums-Intervall die Werte nachträglich holt und ins 'Wetter'-device schreibt. Auch die wandern auf dem Weg dann in die dblog Datenbank. So sieht der one-liner aus (der Leserlichkeit wegen mit '\' als multi-liner geschrieben):
{\
my $day1=time_str2num("2023-01-01");;\
my $dayN=time_str2num("2023-01-31");;\
my $day;;\
my $result;;\
my $thisday=$day1;;\
while ($thisday <= $dayN) {\
    $day=strftime("%Y-%m-%d",localtime($thisday));;\
    $result = fhem "get myCDC rainbyDate $day";;\
    $result =~ /.*Home:(.*):\s(.*)/;;\
    fhem "setreading Wetter ".$1." Regen_gestern ".$2;;\
    $thisday += DAYSECONDS};;\
$result =~ /.*Home:(.*):\s(.*)/;;\
"Tägliche Regenmengen von ".strftime("%Y-%m-%d",localtime($day1))." bis ".strftime("%Y-%m-%d",localtime(time_str2num($1)))." eingelesen";;\
}
In diesem Beispiel holt er alle Januar-Werte ab. Dauerte 18 sec. Ruft man das dann nochmal auf geht's etwas schneller, da das Übertragen und Unzippen der 31 Dateien wegfällt: 12 sec.

Aus Neugier habe ich dann auch den Zeitraum 2023-03-25 bis 2023-03-26 übertragen, in den die Sommerzeitumstellung fiel.
-rw-r--r-- 1 fhem dialout 1620267 Aug 29 12:13 raa01-sf_10000-2303252250-dwd---bin
-rw-r--r-- 1 fhem dialout 1620267 Aug 29 12:13 raa01-sf_10000-2303262150-dwd---bin
Wie man sieht, wechselt im temp_radolan_data-Verzeichnis der timestamp im Dateinamen brav von '2303252250' auf '2303262150'

JoWiemann

Hallo Franz,

ich bin dabei von hermannj aus dem Modul JsonMod die Möglichkeit einer Intervall Definition basierend auf der Linux cron Definition einzubauen. Dauert noch ein bisschen. Dann kann auch eine Uhrzeit vorgegeben werden.

Grüße Jörg
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM