Wetter selbst von yr.no abrufen

Update vom 12.01.2022

Jetzt mit Details zu Dashboard-Ausgabe, inkl. Vorhersage-Chart.

Wetterdaten fürs SmartHome

Rund ums Wetter sammle ich mir eine Vielzahl an Daten aus verschiedenen Quellen. Die Wettervorhersage beziehe ich vom Norwegischen Wetterdienst yr.no, Live-Wetterdaten erhebe ich selbst oder hole sie mir über openSenseMap und Weather.com (Weather Underground) von Wetterstationen aus der Nachbarschaft. Wetterwarnungen kommen vom DWD und ein schickes Niederschlagsradar vom Wetterdienst eines (ehemals) bekannten Wetter-Moderators.

Vorgeschichte

Bisher habe ich für die Wettervorhersage via yr.no den ioBroker-Adapter genutzt. Doch seit der Umstellung der API von xml auf json ist die Anzahl der verfügbaren Werte und damit auch die Anzahl der ioBroker-Objekte explodiert – vieles davon ohne Mehrwert für mich. Dies war mir ein Dorn im Auge, versuche ich doch die Anzahl der Schreibvorgänge auf die SD-Karte klein zu halten.

Also wollte ich die API von yr.no/met.no selbst anzapfen, mit Node-RED ja kein Problem.

So mach ich es

Wenn man die API-Dokumentation aufmerksamer ließt als ich, kann man das ganze recht schnell durchschauen. (Ich brauchte dementsprechend eine Weile.) Man hat die Wahl zwischen dem classic, compact und complete Bericht. Mich interessieren die Temperaturen, die Wetterlage und die erwarteten Niederschlagsmengen. Diese bekomme ich im complete-Bericht.

Man benötigt seine Position als lat/lon. Google Maps verrät beim Rechtsklick auf jeden beliebigen Punkt der Erde die entsprechenden Werte, der erste ist dabei der Breitengrad (lat), der zweite der Längengrad (lon). Ergänzen kann man noch die Höhe über Meeresspiegel – dies ist jedoch optional.

Das Query-String für den Erfurter Dom wäre dann

https://api.met.no/weatherapi/locationforecast/2.0/complete?altitude=194&lat=50.97578937177409&lon=11.023335426472794

Es ist nötig, einen eigenen User-Agent als Identifikation bei der Anfrage mitzusenden, sonst bekommt man einen Fehler „403 Forbidden“. Hier kann man beliebig kreativ sein. Das setzen des Headers geht ganz einfach mit einem Function-Node vor dem HTTP-Request-Node:

msg.headers = {
    "User-Agent": "erfurter-dom-99084"
}
return msg;

Wenn man alles richtig gemacht hat, erhält man als Rückgabe einen wirklich umfangreichen JSON-Datensatz. Dieser enthält Vorhersagedaten für die nächsten 9 Tage. Mich interessieren tatsächlich nur die nächsten 48 Stunden. Auf weiterreichende Wetterentwicklung reagieren meine Flows nicht, und ich habe nicht den Elan, ein allzu umfangreiches Wetter-Dashboard zu bauen. Außerdem ist mir eine weitere Vorhersage eh zu sehr Wahrsagerei.

Die Auswahl der Daten

Da man die API nicht zu oft abfragen darf (und auch nicht will), sollte man die Vorhersagedaten bis zum nächsten API-Abruf zwischenspeichern. Dazu muss man sich überlegen, welche Daten man benötigt.

Beim Stöbern im JSON-Datensatz bin ich darauf gekommen, dass die interessantesten Daten für mich im Bereich der „next_6_hours“ stecken. Sowohl der Symbolcode (= die Wetterlage), als auch die Min-/Max-Temperaturen und die Niederschlagsmenge werden für diese Zeit-Korridore mitgeliefert – und das anfangs stündlich.

{
        "time": "2021-08-30T15:00:00Z",
        "data": {
          "instant": {
            "details": {
              "air_pressure_at_sea_level": 1018.5,
              "air_temperature": 13.8,
              "cloud_area_fraction": 100,
              "cloud_area_fraction_high": 57.8,
              "cloud_area_fraction_low": 100,
              "cloud_area_fraction_medium": 28.1,
              "dew_point_temperature": 12.9,
              "fog_area_fraction": 0,
              "relative_humidity": 94.4,
              "ultraviolet_index_clear_sky": 0,
              "wind_from_direction": 355.9,
              "wind_speed": 2.8
            }
          },
          "next_12_hours": {
            "summary": {
              "symbol_code": "lightrain"
            }
          },
          "next_1_hours": {
            "summary": {
              "symbol_code": "rain"
            },
            "details": {
              "precipitation_amount": 0.3
            }
          },
          "next_6_hours": {
            "summary": {
              "symbol_code": "lightrain"
            },
            "details": {
              "air_temperature_max": 13.9,
              "air_temperature_min": 13.1,
              "precipitation_amount": 0.6
            }
          }
        }
      },

(Nicht verwirren lassen! Alle Zeitangaben sind in UTC)

Die Logik dabei ist:

Zum Zeitpunkt 30.08.2021 17:00 Uhr schaue ich mit „next_6_hours“ auf den Zeitraum zwischen 17:00 und 23:00 Uhr. Auch für den Zeitpunkt 30.08.2021 18:00 Uhr gibt es die „next_6_hours“, welche sich dann auf den Zeitraum 18:00 bis 0:00 Uhr beziehen.

Auf Kosten der Genauigkeit (die bei einer Vorhersage eh relativ ist) und zugunsten der Datensparsamkeit speichere und verarbeite ich also nur jeden sechsten Datensatz bis 42 Stunden in die Zukunft (+6 hours ergibt die 48 Stunden die ich betrachten möchte).

Für diese acht Datensätze (8*6=48 Stunden) habe ich acht Objekte im ioBroker angelegt (bei mir n0, n6, n12, n18, …), in welche ich die inzwischen von JSON in ein JavaScript Objekt konvertierten Daten der „next_6_hours“ als Objekt abspeichere.

Datenaufbereitung

Vor dem Speichern bereite ich die Daten noch ein wenig auf. Ich ordne den Symbolcodes zusätzlich die deutschen Bezeichnungen der Wetterlage zu, ergänze den Wochentag und bereite die Zeit auf, indem ich den Zeitraum errechne, für den diese Werte eine Gültigkeit haben (z.B. Dienstag, 06 – 12 Uhr). Zudem wird der Timestamp des Gültigkeitsstarts errechnet und mit abgelegt.

Nutzung der Wetterdaten

In definierten Regeln

Meine Vorhersage-Objekte (n0 – n42) sind immer aktuell, da ich die Wetterdaten einmal die Stunde abrufe. Somit weiß ich immer, im welchen Objekt welche Zeiträume stecken. Je nachdem wann ein Flow das Wetter abfragt, muss ich also nur den entsprechenden Betrachtungszeitraum festlegen.

Schaut die Rollo-Steuerung zum Beispiel um 9 Uhr, ob sie die südlichen Fenster abschatten sollte, dann schaut sie u.a. nach den Höchstwerten von „n0“, also wie warm es maximal zwischen 9 und 15 Uhr wird. Soll das Haus am Abend Bescheid sagen, dass die Fenster dank kühler Abendluft endlich geöffnet werden können, dann schaut es erst, wie warm es am nächsten und übernächsten Tag wird („n18“, „n42“).

Im Dashboard / UI

Natürlich schauen nicht nur automatische Steuerungen nach dem Wetter – ich gebe die Vorhersage auch im Dashboard aus. Neben der noch ausbaubaren tabellarischen Aufbereitung habe ich dafür inzwischen auch ein Temperatur-Vorhersage Chart.

Da ich die Daten direkt als JavaScript Objekt in das ioBroker Objekt abspeichere, kann ich auch direkt nach dem Auslesen des Objekts auf die Werte zugreifen.

msg.payload.details.air_temperature_max

Die tabellarische Ausgabe basiert somit auf einfachen Abfragen und Textausgaben, da alle Daten ja schon passend aufbereitet wurden.

Die entsprechenden ui_text – Nodes, welche durch CSS Klassen etwas gestaltet werden:

1. und 2. Spalte (n0)
3. Spalte (w0)

Für das Temperatur-Vorhersage-Diagramm müssen alle Objekte (iobroker list Node) geladen und daraus die passende Chart-JSON generiert werden. (siehe Flow Download)

Beispielhafte JSON zur Befüllung eines Node-RED Dashboard Charts

[{"series":["min °C","max °C"],"data":[[-0.6,-0.5,3.7,1.9,0.5,0.6,3.2,3.6],[1,2.5,5.8,3.8,1.3,2.1,5,4]],"labels":[1,7,13,19,1,7,13,19]}]

Da der abzubildende Zeitraum in der Zukunft liegt, können die Werte nicht anhand eines timestamps verortert werden, sondern brauchen feste Bezeichnungen. Hierbei habe ich mich für die Mitte des sechs Stunden Zeitraums entschieden.

Flows als Download

Wer es ausprobieren möchte, braucht im ioBroker unter 0_userdata.0.Vorhersage entsprechende Objekte und kann nach dem Import des folgenden Flows direkt loslegen.

Gedanken zur KWL

Kontrollierte Wohnraumlüftungen (kurz KWL) sind eine feine Sache. Man stelle sich vor, man müsste tagsüber mehrmals lüften … Klar: sie ist keine Klimaanlage. Und doch sollte man nicht nur beim Thema „wärmen“, bzw. Wärme erhalten im Winter (was sie über die Wärmerückgewinnung ja macht) ein paar Dinge beachten.

Standort

Wer die Gelegenheit hat, den Standort des KWL Geräts zu bestimmen, tue dies weise. So sollten sie klar innerhalb der thermischen Hülle des Hauses stehen – für die entsprechende Effizienz im Winter. Erfahrungen zeigen aber auch: der Heizraum ist meist nicht der geeignete Ort für das Gerät – gerade in einer Kombination mit Solarthermie. Die steht im Sommer schließlich fast unbegrenzt zur Verfügung und hebt die Temperatur im Heizraum (wo in der Standardausführung meist auch der Warmwasser-Speicher steht) auf unschöne Höhen. Jegliche Kaltluft, die möglicherweise in der Nacht die KWL dank Bypass ohne Wärmerückgewinnung passieren könnte, wird so stark durch die Heizraumtemperatur beeinflusst, dass nicht mal eine minimale Abkühlung der Räume über die KWL stattfindet. Also: vielleicht gibt es einen Wäscheraum oder einen Kellerraum – sofern man über einen solchen verfügt – in dem die KWL besser aufgehoben ist.

Funktionen / Abhilfe

Eine wichtige Funktion für ein angenehmes Raumklima ist der schon erwähnte Sommer-Bypass. Er leistet – wenn nicht von der Raumtemperatur beeinflusst – einen Beitrag für ein angenehmes kühles Raumklima im Sommer, indem er die Wärmerückgewinnung umgeht. Interessant und wichtig – auch für alle, die das gleiche Dilemma der Interaktion zwischen Solarthermie und Lüftung haben – ist der Fensterlüftungsmodus. Bei ihm wird die Zuluft komplett abgeschaltet, sodass die KWL nur absaugt und das Zuströmen kalter Luft (in der Nacht) durch die Fenster unterstützt.

Beispiel: Pluggit

Bei meinem Lüftungsgerät von Pluggit Avent P310 lässt sich der Fensterlüftungsmodus über die Modbus Schnittstelle aktivieren:

modbus.0.holdingRegisters.40169_prmRamIdxUnitMode

Manuel = 4 / Wochenprogramm = 8 / Start Sommer = 2048 / Ende Sommer = 2048

Leider ist es ein Toggle – sprich man sendet sowohl zum Einschalten, als auch zum Ausschalten „2048“.

Wetterradar im Dashboard

Ich wollte gern ein Wetterradar im Dashboard haben. Doch an solche grafischen Darstellungen kommt man ja nicht immer ohne weiteres (kostenlos) ran – und der DWD bietet nur eine Drei-Länder-Darstellung.

Also musste etwas CSS her, um mittels eines Node-RED template Node nur einen Bildausschnitt darzustellen.

<div style="position:absolute;width: 296px;height: 250px; background-color: #BEBEBE;overflow: hidden;">
<img src="https://www.dwd.de/DWD/wetter/radar/radfilm_thu_akt.gif" style="position: absolute;top:-250px;	overflow: hidden;" />
</div>

Ich definiere einen Container mit overflow:hidden; sodass alles was nicht reinpasst auch nicht angezeigt wird. Mittels top und left kann ich das Bild entsprechend vertikal und horizontal verschieben.

Update 2021

Inzwischen bin ich auf das Radar eines anderen Wetterdienstes umgestiegen. Da dieser bei der Fremd-Verwendung nicht so freigiebig ist, wie der DWD, erwähne ich dessen Namen hier nicht und sagen nur so viel: mit einem simuliertem Website-Zugriff (http request-Node) und der Übermittlung des Cookies und des richtigen Referer-Headers beim Abruf der Radar-Grafik ist so manche unwirksame Sperre überwindbar. Die Grafik speichere ich dabei lokal zwischen (httpStatic).

Ein change-Node zwischen simuliertem Website-Zugriff und Grafik-Abruf