Seite auswählen

Wunderground Wetter mit einfachem HM-Skript holen

,
Wunderground Wetter mit einfachem HM-Skript holen
Print Friendly

In einem anderen Blog wurde sehr ausführlich und gut beschrieben, wie man die Wetterdaten von wunderground.com in die Homematic bekommt.

http://homematic-forum.de/forum/viewtopic.php?f=31&t=10071&hilit=wunderground
Allerdings verwendet diese Lösung ein TCL-Skript, was insbesondere für den Anfänger nur mit Aufwand implementierbar ist und dementsprechend Fehlermöglichkeiten hat.Hier wird ein „Kochrezept“ für die Implementierung eines wunderground.com-Wetterdatenabrufes beschrieben, der nur mit einem HM-Skript arbeitet:
1  API-Key von Wunderground besorgen wie unter o.a. Link beschrieben
2  Insgesamt 14 Systemvariable entsprechend der Vorgaben im nachfolgenden Skript sorgfältig ohne Schreibfehler (!) anlegen
(schon bei einem kleinsten Schreibfehler oder fehlender Systemvariable läuft das Skript nicht durch!)
3  Im nachfolgenden Skript den API-Key in die URL-Zeile eintragen und vorher die Funktion der URL ausprobieren
(im Browser aufrufen und dann erhält man den aktuellen XML-Wetterfile im Browser angezeigt!).
4  Ein einfaches WebUI-Programm erstellen, das auf Tastendruck oder alle 30min das nachfolgende Skript aufruft.Fertig!
Hinweis: Das Skript benutzt CuxD-zum Aufruf des Wunderground-Servers. Wenn ein entsprecchendes CUxD-Gerät vorher nicht installiert wurde, dann kann man auch die in der CCU standardmässig verfügbare Abfrage mit system.Exec verwenden. Dazu im Skript die entsprecheenden CUxD-Zeilen mit Rufzeichen auskommentieren und im Gegenzug bei den  system-Exec-Zeilen die Ausrufezeichen entfernen.
.
HM-Skript   
!Stand 03.04.2014  http://homematic-forum.de/forum/viewtopic.php?f=31&t=17209
        !zuerst folgende Systemvariablen anlegen
        !Achtung: keine vergessen und exakte Schreibweise mit Drag&Drop
        !W_Station                        Zeichenkette
        !W_Aktualisierung             Zeichenkette
        !W_Bedingungen               Zeichenkette
        !W_Temperatur                  Zahl                     °C
        !W_Luftfeuchte                  Zahl                      %
        !W_Windbedingungen       Zeichenkette
        !W_Windrichtung               Zeichenkette
        !W_Windrichtg                   Zahl                       °
        !W_Windgeschwindigkeit   Zahl                     km/h
        !W_Windboeen                  Zahl                     km/h
        !W_Luftdruck                      Zahl                      mb
        !W_Luftdrucktrend             Zeichenkette
        !W_Taupunkt                      Zahl                     °C
        !W_UV                                Zeichenkette
 
        var url = "http://api.wunderground.com/api/<api-key>/conditions/lang:DL/q/Germany/Neuwied.xml";
 
        !hier ist die Abfrage mit CUxD
        dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("wget -q -O - '"#url#"'");
        dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
        string wetter_xml = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
 
        !hier ist die Abfrage mit system.Exec
        !string stdout;
        !string stderr;
        !system.Exec("wget -q -O - '"#url#"'", &stdout, &stderr);
        !WriteLine(stdout);
        !string wetter_xml = stdout;
        !WriteLine(wetter_xml);
 
        !Beim XML-File den ueberfluessigen Header entfernen
        integer laenge = wetter_xml.Length();
        integer wort_position = wetter_xml.Find("display_location");
        wetter_xml = wetter_xml.Substr(wort_position, (laenge - wort_position));
        !WriteLine(wetter_xml);
 
        !Daten mit Suchworten aus XML-File ausfiltern:
 
        !string word = "full";
        string word = "city";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        dom.GetObject("W_Station").State(daten);
 
        !string word = "observation_time";
        string word = "observation_time_rfc822";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        !daten = daten.Substr(0, (word_position -2));
        daten = daten.Substr(0, (word_position -11));
        dom.GetObject("W_Aktualisierung").State(daten);
 
        string word = "weather";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        dom.GetObject("W_Bedingungen").State(daten);
 
        string word = "temp_c";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        real zahl = daten.ToFloat();
        dom.GetObject("W_Temperatur").State(zahl);
 
        string word = "relative_humidity";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        integer zahl = daten.ToFloat();
        dom.GetObject("W_Luftfeuchte").State(zahl);
 
        string word = "wind_string";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        dom.GetObject("W_Windbedingungen").State(daten);
 
        string word = "wind_dir";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        word_laenge =daten.Length();
        string anfangsbuchstabe = daten.Substr(0,1);
        ! Umlaute korrigieren
        !
        ! N # Nord ***
        if (anfangsbuchstabe == "N") {
           !
            if (daten == "Nordwest") {daten = "Nord-West" ;}
        }
 
        ! S # Süd ***
        if (anfangsbuchstabe == "S") {
           ! 4 # Süd
           if (word_laenge == 4)  {daten = "Süd";}
           ! 8 # Südwest
           if (word_laenge == 8)  {daten = "Süd-West";}
           ! 12 # Süd-Südost
           if (word_laenge == 12) {daten = "Süd-Süd-Ost" ;}
             ! 13
           if (word_laenge == 13) {daten = "Süd-Süd-West" ;}
        }
 
        ! W # Westen
        if (anfangsbuchstabe == "W") {
           ! 13 # West-Südwest
            if (word_laenge == 13) {daten = "West-Süd-West" ;}
        }
 
        ! O # Osten
        if (anfangsbuchstabe == "O") {
           ! 11 # Ost-Südost
           if (word_laenge == 11) {daten = "Ost-Süd-Ost" ;}
        }
        dom.GetObject("W_Windrichtung").State(daten);
        !WriteLine(daten);
 
 
        string word = "wind_degrees";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        integer zahl = daten.ToFloat();
        dom.GetObject("W_Windrichtg").State(zahl);
 
        string word = "wind_kph";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        integer zahl = daten.ToFloat();
        dom.GetObject("W_Windgeschwindigkeit").State(zahl);
 
        string word = "wind_gust_kph";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        integer zahl = daten.ToFloat();
        dom.GetObject("W_Windboeen").State(zahl);
 
        string word = "pressure_mb";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        integer zahl = daten.ToFloat();
        dom.GetObject("W_Luftdruck").State(zahl);
 
        string word = "pressure_trend";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        dom.GetObject("W_Luftdrucktrend").State(daten);
 
        string word = "dewpoint_c";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        real zahl = daten.ToFloat();
        dom.GetObject("W_Taupunkt").State(zahl);
 
        string word = "UV";
        integer word_laenge = word.Length();
        integer word_position = wetter_xml.Find(word);
        string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
        integer word_position = daten.Find(word);
        daten = daten.Substr(0, (word_position -2));
        real zahl = daten.ToFloat();
        dom.GetObject("W_UV").State(zahl);

Changelog: 03.04.2014 Umlaute Himmelsrichtungen korrigiert, UV-Kennwert zugefügt.

Fähigkeiten

Gepostet am

8. Juli 2014

74 Kommentare

  1. Hi,

    super Skript, danke Dir!
    Eine Frage habe ich noch: Hast Du eine Liste der Parameterwerte, die als Wetterbedingung zurückkommen können? Ich habe noch keinen Sonnenstrahlungsmesser gebaut, daher gehe ich bei der Rolloadensteuerung derzeit auf „Heiter“ und „Teils wolkig“, kenne aber schlicht nicht alle möglichen kommenden Parameterwerte, um auf diese entsprechend reagieren zu können – bei „Wolkig“ o.ä. möchte ich den Rolladen bspw. wieder öffnen lassen…

    Gruß, Jan

  2. Wenn man das Skript ansieht, dann ist das eigentlich dort beschrieben! Aber ich nehme die Anregung gerne an und habe einen entsprechenden Hinweis hinzugefügt.

  3. Tolle Script, wenn man hinzufügen könnte dass man im CUXD eine Gerät System28 Exec anlegen muss damit das ganze auch funtzt….

    Hatte es mal vor nem Jahr gemacht und bei der CCU2 eines Freundes habe ich nun 2 Stunden durch Suchen verbraucht

    Der Schritt wird ganz ausgelassen ?
    Schade
    Sonst Daumen hoch und vielen Dank für das Script

  4. Hallo, seit der neuen Firmware vom 3/2017 kommt beim script folgende Fehlermeldung:

    Error 1 at row 20 col 246 near ^ -q -O – ‚“#url#“‚“, &stdout, &stderr);
    WriteLine(stdout);
    strin
    Parse following code failed:
    !Stand 03.04.2014 http://homematic-forum.de/forum/viewtopic.php?f=31&t=17209
    !zuerst folgende Systemvariablen anlegen
    !Achtung: keine vergessen und exakte Schreibweise mit Drag&Drop
    !W_Station Zeichenkette
    !W_Aktualisierung Zeichenkette
    !W_Bedingungen Zeichenkette
    !W_Temperatur Zahl °C
    !W_Luftfeuchte Zahl %
    !W_Windbedingungen Zeichenkette
    !W_Windrichtung Zeichenkette
    !W_Windrichtg Zahl °
    !W_Windgeschwindigkeit Zahl km/h
    !W_Windboeen Zahl km/h
    !W_Luftdruck Zahl mb
    !W_Luftdrucktrend Zeichenkette
    !W_Taupunkt Zahl °C
    !W_UV Zeichenkette

    !var url = „http://api.wunderground.com/api//conditions/lang:DL/q/Germany/Neuwied.xml“;
    var url = „http://api.wunderground.com/api/e01a7dc2242b9994/conditions/lang:DL/q/Germany/Zweibr%C3%BCcken.xml;

    !hier ist die Abfrage mit system.Exec;
    string stdout;
    string stderr;
    system.Exec(„wget -q -O – ‚“#url#“‚“, &stdout, &stderr);
    WriteLine(stdout);
    string wetter_xml = stdout;
    !WriteLine(wetter_xml);

    !Beim XML-File den ueberfluessigen Header entfernen
    integer laenge = wetter_xml.Length();
    integer wort_position = wetter_xml.Find(„display_location“);
    wetter_xml = wetter_xml.Substr(wort_position, (laenge – wort_position));
    !WriteLine(wetter_xml);

    !Daten mit Suchworten aus XML-File ausfiltern:

    !string word = „full“;
    string word = „city“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    dom.GetObject(„W_Station“).State(daten);

    !string word = „observation_time“;
    string word = „observation_time_rfc822“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    !daten = daten.Substr(0, (word_position -2));
    daten = daten.Substr(0, (word_position -11));
    dom.GetObject(„W_Aktualisierung“).State(daten);

    string word = „weather“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    dom.GetObject(„W_Bedingungen“).State(daten);

    string word = „temp_c“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    real zahl = daten.ToFloat();
    dom.GetObject(„W_Temperatur“).State(zahl);

    string word = „relative_humidity“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    integer zahl = daten.ToFloat();
    dom.GetObject(„W_Luftfeuchte“).State(zahl);

    string word = „wind_string“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    dom.GetObject(„W_Windbedingungen“).State(daten);

    string word = „wind_dir“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    word_laenge =daten.Length();
    string anfangsbuchstabe = daten.Substr(0,1);
    ! Umlaute korrigieren
    !
    ! N # Nord ***
    if (anfangsbuchstabe == „N“) {
    !
    if (daten == „Nordwest“) {daten = „Nord-West“ ;}
    }

    ! S # Süd ***
    if (anfangsbuchstabe == „S“) {
    ! 4 # Süd
    if (word_laenge == 4) {daten = „Süd“;}
    ! 8 # Südwest
    if (word_laenge == 8) {daten = „Süd-West“;}
    ! 12 # Süd-Südost
    if (word_laenge == 12) {daten = „Süd-Süd-Ost“ ;}
    ! 13
    if (word_laenge == 13) {daten = „Süd-Süd-West“ ;}
    }

    ! W # Westen
    if (anfangsbuchstabe == „W“) {
    ! 13 # West-Südwest
    if (word_laenge == 13) {daten = „West-Süd-West“ ;}
    }

    ! O # Osten
    if (anfangsbuchstabe == „O“) {
    ! 11 # Ost-Südost
    if (word_laenge == 11) {daten = „Ost-Süd-Ost“ ;}
    }
    dom.GetObject(„W_Windrichtung“).State(daten);
    !WriteLine(daten);

    string word = „wind_degrees“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    integer zahl = daten.ToFloat();
    dom.GetObject(„W_Windrichtg“).State(zahl);

    string word = „wind_kph“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    integer zahl = daten.ToFloat();
    dom.GetObject(„W_Windgeschwindigkeit“).State(zahl);

    string word = „wind_gust_kph“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    integer zahl = daten.ToFloat();
    dom.GetObject(„W_Windboeen“).State(zahl);

    string word = „pressure_mb“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    integer zahl = daten.ToFloat();
    dom.GetObject(„W_Luftdruck“).State(zahl);

    string word = „pressure_trend“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    dom.GetObject(„W_Luftdrucktrend“).State(daten);

    string word = „dewpoint_c“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    real zahl = daten.ToFloat();
    dom.GetObject(„W_Taupunkt“).State(zahl);

    string word = „UV“;
    integer word_laenge = word.Length();
    integer word_position = wetter_xml.Find(word);
    string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
    integer word_position = daten.Find(word);
    daten = daten.Substr(0, (word_position -2));
    real zahl = daten.ToFloat();
    dom.GetObject(„W_UV“).State(zahl);

    Hat bis zu den letzten Firmware Versionen TOP funktioniert!
    Gr. Thomas

  5. Ich hab jetzt nur noch ein Problem mit dem Ortsnamen. Ich würde gerne die Daten einer bestimmten Station haben. Ich kann aber ja nur den Ortsname.xml angeben. Welche Station wird dann gewählt? Kann ich nicht irgendwie eine bestimmte Station definieren?

  6. Ich hab jetzt lang rum probiert. Für alle die das Problem haben, dass die Variablen auf 0 bleiben: Ich habe alle Leerzeilen entfernt. Auch die Leertasten am Zeilenanfang. Wollt ihr Leerzeilen einfügen, dann am besten mit !; Sollte eine Leerzeile nur mit ! geschrieben sein, geht das Script vom einem Auskommentieren der Folgezeile aus. Am besten ganz ohne Leerzeilen, leider wird es dann halt etwas unleserlich. Aber seitdem funktioniert es bei mir.

  7. Eines verstehe ich grad noch nicht. Wie bekomme ich eine bestimmte Station in die URL? Wo finde ich den zugörigen Namen der xml-Datei?

  8. Hallo,

    Mittlerweile läuft das Script ohne Fehler durch.
    Erhalte aber leider lauter 0 Werte.
    Was mache ich falsch?

  9. Hallo,

    im Script gibt es einen Absatz mit der Bemerkung, dass die Umlaute korrigiert werden müssen.
    Ist dies eine Funktion im Script selber oder muss im Script z.B. […! S # Süd ***
    if (anfangsbuchstabe == „S“) {
    ! 4 # Süd

    dies korrigiert werden, damit es funktioniert. Wenn ja, korrigiert auf „Sued“ oder „Süd“

    Vielen Dank
    Friedhelm Rook

  10. @HB

    Habe genau das gleiche Problem und nur „0“ Werte in der Auswertung. Hast du schon eine Lösung gefunden?

  11. Hab alles so gemacht wie hier beschrieben. Leider werden aber die Systemvariabeln nicht befüllt. Gibts da noch einen Tipp oder kann es sein das zur aktuellsten CCU2 Firmware nicht mehr passt ?

  12. Moin,
    funktioniert prima, wenn man nicht die CuX Variante, sondern die SystemExec verwendet. Dazu die entsprechenden Zeilen aaskommentiert, bzw. kommentiert.

    Die Umlautersetzung hat noch Herausforderungen.

    Liebe Grüße
    Matthias

  13. Habe alles 10x kontrolliert und finde das Problem nicht.
    Habe folgenden fehler lt. log:

    Oct 23 22:30:06 homematic-ccu2 daemon.info cuxd[3266]: pclose(wget -q -O – ‚http://api.wunderground.com/api/1234567890/conditions/lang:DL/q/Germany/xxxx.xml‘) exit(4) 5s

    Oct 23 22:30:06 homematic-ccu2 local0.err ReGaHss: Error: IseXmlRpc::CallGetValue: XmlrpcTypeToIseVal failed [../Platform/DOM/iseXmlRpc.cpp (1455)]

    Oct 23 22:30:06 homematic-ccu2 local0.err ReGaHss: Error: IseHssDP::ReadValue: CallGetValue failed; sVal = 4 [../Platform/DOM/iseDOMdpHSS.cpp (130)]

Kommentar absenden

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Translate »