55_GDS.pm - komplett überarbeitet - RC1

Begonnen von betateilchen, 09 Oktober 2015, 21:05:42

Vorheriges Thema - Nächstes Thema

betateilchen

Im SVN Repository befindet sich im commit #9416 der erste release candidate für das überarbeitete Modul 55_GDS.pm
Diese Datei befindet sich aktuell im Verzeichnis ./contrib/55_GDS.2015 und muss manuell in das Verzeichnis ./FHEM kopiert werden.

Da der DWD aktuell die Datenstrukturen seiner Grundversorgung massiv umbaut, musste ich das Modul ohnehin in Angriff nehmen, um diesen Änderungen gerecht zu werden. Dabei habe ich eine ganze Menge Dinge umgesetzt, die schon lange auf meiner Ideenliste standen.

Ausserdem habe ich die von jensb in diesem Thread vorgeschlagenen Erweiterungen für forecasts und weblinks eingebaut.

Wichtige Informationen und vorgenommene Änderungen:


  • Das Modul sollte mit RC-Versionen noch nicht in wichtigen Produktivumgebungen verwendet werden.
  • Das Modul funktioniert nicht mehr unter Windows.
  • Das Modul benötigt keine neuen zusätzlichen perl-Modul gegenüber der bisherigen offiziellen Version.
  • Das Modul benutzt ab sofort ausschließlich ftp-Transfers, der LWP::UA wird nicht mehr benötigt.
  • Die ftp-Übertragungen arbeiten nun nonblocking.
  • Das Modul führt erste Datenaktualisierungen direkt nach dem fhem-Start durch.
  • Das Modul kann weblinks analog zum Weather-Modul bereitstellen.
  • Das Modul stellt Wettervorhersagen als Text und als Readings bereit.
  • Die Version ist nahezu vollständig kompatibel zu bisherigen device-Definitionen. *
  • * Ausnahme bei der Kompatibilität: Der Befehl "set <name> rereadcfg" wurde entfernt. Stattdessen kann der auch bisher schon vorhandene Befehl "get <name> rereadcfg" verwendet werden
  • Neue Optionen für "set clear ...": conditions,forcasts

Bekannte Bugs / offene Punkte:


  • Die Dokumentation ist noch nicht komplett überarbeitet
  • Über den Verbleib des html-Generators im Modul habe ich noch nicht endgültig entschieden. Eigentlich halte ich ihn für entbehrlich.
  • Für die Funktionsweise der forecast-Aufbereitung sowie des html-Generators bin ich nicht verantwortlich, dafür gibt es von mir keinen Support.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

jensb

Den Support für die Vorhersage kann ich zur Verfügung stellen. Sollten dabei Codeänderungen am GDS-Modul  erforderlich werden, kann ich einen Patch vorbereiten und wir stimmen uns ab.
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

betateilchen

Soeben wurde RC2 veröffentlicht. Darin enthalten sind folgende Änderungen:



#   2015-10-11  renamed   99_gdsUtils.pm to GDSweblink.pm
#               changed   load GDSweblink.pm in eval() on module startup
#
#   2015-10-10  added     attribute gdsHideFile to hide "GDS File" Menu
#               added     optional parameter "host" in define() to override default hostname
#
#               changed   weblink generator           moved into 99_gdsUtils.pm
#               changed   perl module List::MoreUtils is no longer used
#               changed   perl module Text::CSV is no longer needed
#               changed   use binary mode for all ftp transfers to preven errors in images
#
#               fixed     handling for alert items msgType, sent, status
#               fixed     handling for alert messages without "expires" data
#
#               updated   commandref documentation

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

#3
Zitat von: jensb am 11 Oktober 2015, 12:10:45

Sollten dabei Codeänderungen am GDS-Modul  erforderlich werden, kann ich einen Patch vorbereiten


Apropos patch... ich hab da mal was vereinfacht :)



sub getListForecastStations($) {
my ($hash)  = @_;
my $name    = $hash->{NAME};
my @regions = keys(%rmapList);
my @a;

foreach my $region (@regions) {
my $areaAndTime = $region.'_morgen_spaet';
retrieveFile($hash, "forecasts", $areaAndTime, undef,undef);
sleep 1;
my $fileName = $tempDir.$name."_forecasts";
my ($err,@data) = FileRead({FileName=>$fileName,ForceType=>"file" });
return "GDS $name: error reading $fileName" if($err);

splice(@data, 0,2);
splice(@data,-2);
map ( push(@a,"$region/".(split(/\s/,latin1ToUtf8($_),2))[0]), @data);
}
   
Log3($name, 4, "GDS $name: forecast data not found") unless (!@a);

@a = sort(@a);
  $fList = join(",", @a);
$fList =~ s/\s+,/,/g; # replace multiple spaces followed by comma with comma
$fList =~ s/\s/_/g;   # replace spaces in stationName with underscore for list in frontend

return;
}



Aber eigentlich könnte man $fList ja auch als "Abfallprodukt" aus dem Lesen der Vorhersagedaten generieren.
Das muss ich mir noch anschauen.


Mit dem ganzen nonblocking-Gedöns bin ich generell noch nicht so ganz glücklich.
Aber es funktioniert derzeit erstmal :)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

jensb

Die sub getListForecastStations ist nun deutlich kompakter. Es gibt allerdings manchmal Vorhersagedateien ohne Trenner zwischen Stationsname und Temperatur, wobei die Temperatur dann ungültig "---" ist. Bin mir nicht sicher, was der neue Code daraus macht.

Klar, die Stationsliste ist ein Abfallprodukt der Vorhersagedaten, aber für die Stationsiste braucht man alle Regionen für eine beliebigen Zeitpunkt, während man für die Stationsaktualisierung alle Zeitpunkte einer Region benötigt. Lädt man immer alles, dauert der Update deutlich länger.

Um das nonblocking bei der FTP-Übertragung voll ausnutzen zu können, müsste man statt des sleep einen Sekundentimer einstellen und erst mal mit return die Kontolle an FHEM zurück geben. Wenn der Timer auslöst, prüft man, ob der FTP-Transfer fertig ist und arbeitet dann weiter oder wartet nochmal bis zum nächsten Timerevent. Außerdem muss man sich noch merken, womit man weiter machen will, wenn der FTP-Transfer fertig ist (Istwerte, Vorhersagewerte, Warnungen,  etc.). FHEM würde dadurch nicht mehr geblockt, aber der Code müsste dafür angepasst werden.
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

betateilchen

Zitat von: jensb am 11 Oktober 2015, 19:47:29
Die sub getListForecastStations ist nun deutlich kompakter. Es gibt allerdings manchmal Vorhersagedateien ohne Trenner zwischen Stationsname und Temperatur, wobei die Temperatur dann ungültig "---" ist. Bin mir nicht sicher, was der neue Code daraus macht.

Was meinst Du mit "Temperatur ungültig"? Steht dann da "stadtnamexyz---" ohne ein Leerzeichen dazwischen?

Grundsätzlich ist mein Gedankengang, in einem einzigen nb-Funktionsaufruf per FTP die Dateiliste auf dem Server zu lesen und in der gleichen Session alle (ca. 80) Dateien abzuholen und ihren Inhalt in einem Hash zu speichern. Das funktioniert auch soweit, aber ich bekomme den Hash nicht aus der nb-Funktion an die finishFn zurückgegeben.

Aus dem Hash können danach alle für die Vorhersagen benötigten Daten aufbereitet werden, ohne nochmal eine Übertragung starten zu müssen.

Wenn ich das gelöst habe, werde ich das Verfahren auch für die anderen retrieval-Funktionen übernehmen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

jensb

ZitatWas meinst Du mit "Temperatur ungültig"? Steht dann da "stadtnamexyz---" ohne ein Leerzeichen dazwischen?
Yep. Du könntest hierfür eine Variante von Zeile 1421 meiner letzten Version $line =~ s/---/   ---/g;   # column distance may drop to zero between station name and invalid temp "---" -> prepend 3 spaces vor dem split einfügen.

Zitat... und ihren Inhalt in einem Hash zu speichern

Habe bei meinen letzten nb-Experimenten so was ähnliches versucht. Von hier aus komme ich aber nicht an den Code, so daß ich nicht nachsehen kann, ob ich da auch einen Hash, ein Array oder einen CSV-String für die Rückmeldung verwendet hatte.

Alternativ könntest du mit dem FTP-Fetch einen temporären Datei-Mirror erstellen und nur eine Fertigmeldung versenden. Dann muss man allerdings die Dateien mit File-IO noch mal laden. Der Hash wäre schon besser.
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

betateilchen

Die Sache mit dem Hash für alle Forecasts ist nonblocking gelöst. Die Übertragung und Aufbereitung aller 88 aktuellen Dateien in den Hash dauert auf meinem Raspberry ca. 20 Sekunden - im Hintergrund :)

Die Extraktion der Daten aus dem Hash ist nun der nächste Schritt.

Und das mit dem "---" geht auch einfacher. Da nach dieser Logik nach einem Stadtnamen nur ein Leerzeichen oder ein Minuszeichen kommen kann, muss ich ja nur das split-Kriterium anpassen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

jensb

88 Dateien in 20 s ist für DWD-Verhältnisse gut, vor allem, wenn es im Hintergrund passiert. Für Alerts, Conditions, Forecasts und ein paar der Karten hat es auf meinem RPi bisher allein schon ca. 15 s gedauert.
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

Kuzl

Hallo betateilchen,

was hältst du davon, eine Funktionalität einzubauen, die anderen Readings wie alarms, warnings und die maps automatisch zu aktualisieren?
Man spart sich dann das notify (und das Log wird nicht beschrieben wenn keine Meldungen vorliegen)

Intressant wär das ganze evtl in das vorhandene Attribut einzubauen und dann konfigurierbar zu machen, was upgedatet werden soll (der Hash muss ja scheinbar in jedem Fall neu vom Server geholt werden oder?)

Viele Grüße,
Kuzl

betateilchen

Zitat von: Kuzl am 12 Oktober 2015, 13:17:05

was hältst du davon, eine Funktionalität einzubauen, die anderen Readings wie alarms, warnings und die maps automatisch zu aktualisieren?


Nichts - aus verschiedenen Gründen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Kuzl

Kannst du die mir bitte erläutern?

Ich bin ein Freund von Modulen, die zum Anzeigen von aktuellen Informationen keine notifys/at benötigen.
Aber wenns wirklich nicht vertretbar ist - Könntest du den Returnstring von "get <name> alarm ....." entfernen?
Denn wenn die einzige Möglichkeit von aktuellen Wetterwarnungen über ein at ist, wird der Returnstring dann immer ins Log eingetragen und man hat keine Möglichkeit das abzustellen (zuminderst kenne ich keine).

betateilchen

Erläuterung:

Ein automatisches Aktualisieren der alerts und warnings würde der (meiner) ursprünglichen Aufgabenstellung widersprechen, wegen der ich das Modul vor zweieinhalb Jahren überhaupt geschrieben habe. Bei mir werden sequentiell MEHRERE alerts für unterschiedliche Regionen abgefragt.

Am Rückgabewert von get werde ich nichts ändern. Dein Problem mit dem Log kann ich nicht nachvollziehen, bei mir stehen keinerlei Ergebnisse eines "get <name> alerts <region>" im Log. Du musst eigentlich nur in dem at, das die alerts prüft, den verbose-Level auf 2 stellen.

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Kuzl

Okay das ist durchaus ein Argument, aber warum dann nicht einfach ein weiteres Device für eine weitere Region ablegen, so wie es im restlichen FHEM auch gemacht wird?

bei dem AT muss ich nochmal nachschaun, kann sein dass ich das nicht gemacht habe.

betateilchen

Zitat von: Kuzl am 13 Oktober 2015, 07:18:27
aber warum dann nicht einfach ein weiteres Device für eine weitere Region ablegen

Weil ich das aus Performancegründen damals beim Moduldesign anders entschieden habe.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!