Wetterdaten von Open-Meteo im Webbrowser anzeigen

Kate­go­rien: ,


Voll­stän­di­ge Anzei­ge
Vor­her­sa­ge aus­blen­den

Ziele des Projekts

In einem Web­brow­ser wer­den …

  • die aktu­el­len Wet­ter­da­ten von Open-Meteo
  • der aktu­el­le C02-Wert, die Fein­staub­kon­zen­tra­ti­on PM2,5 , der Ozon­wert, der UV-Index und der Index für die Luft­qua­li­tät (E)AQI
  • die Wet­ter­vor­her­sa­ge für drei Tage

… ange­zeigt

Konfiguration der Mikrocontroller

Open-Meteo

Open-Meteo ist eine quell­of­fe­ne Soft­ware, die unter der Lizenz ⤷CC BY 4.0 ver­öf­fent­lich wird. Die Gesell­schaft hat ihren Sitz in der Schweiz. Für die Nut­zung ist kei­ne Anmel­dung erfor­der­lich. Die nicht-kom­mer­zel­le Nut­zung erlaubt höchs­tens 10.000 Auf­ru­fe pro Tag, 5.000 pro Stun­de und 600 pro Minu­te. Wer­den die Daten im Inter­net ver­öf­fent­licht, muss die Web­sei­te einen Link zu Open-Meteo ent­hal­ten. Weil die Daten aber nur im pri­va­ten Netz dar­ge­stellt wer­den, ist aus mei­ner Sicht die­ser Link nicht not­wen­dig.
Quel­le: ⤷https://open-meteo.com/en/terms

DWD ICON API

Die Platt­form Open-Meteo stellt Wet­ter­da­ten aus ver­schie­de­nen Quel­len zur Ver­fü­gung, ich habe mich für den Deut­schen Wet­ter­dienst ent­schie­den:

  • aktu­el­le Wet­ter­da­ten:
    Tem­pe­ra­tur, Luft­feuch­tig­keit, Luft­druck, Nie­der­schlag, Wind­stär­ke, Wind­rich­tung
  • 7-Tage Wet­ter­vor­her­sa­ge tage­wei­se
    Tem­pe­ra­tur minimum/maximum, „gefühl­te“ Tem­pe­ra­tur, Regen­wahr­schein­lich­keit, Sonnenaufgang/Sonnenuntergang

Als Ers­tes musst du die Zeit­zo­ne wäh­len und über den But­ton „Search“ dei­nen Ort suchen:

⤷https://open-meteo.com/en/docs/dwd-api

Wenn du selbst die API kon­fi­gu­rie­ren willst:⇒Aus­wahl der Wet­ter­da­ten

Du kannst den Auf­ruf der API mit den gewähl­ten Para­me­tern über­neh­men, du musst ledig­lich in Zei­le 8 die für dei­nen Ort gül­ti­gen Koor­di­na­ten inner­halb der Adres­se aus­tau­schen:

Air Quality API

Zunächst musst du dei­ne Stadt und die Zeit­zo­ne aus­wäh­len:

⤷https://open-meteo.com/en/docs/air-quality-api


Die APi stellt sehr vie­le Daten zur Ver­fü­gung, ich habe mich auf ⇒CO2, Fein­staub PM2,5 , den Ozon­wert, den UV-Index und den EAQI beschränkt.
Als Fein­staub PM2,5 (Par­ti­cu­la­te Mat­ter) bezeich­net man Par­ti­kel mit einem Durch­mes­ser von weni­ger als 2,5 Mikro­me­ter (µm).
EAQI (Euro­pean Air Qua­li­ty Index) ist die Zusam­men­fas­sung und Gewich­tung ver­schie­de­ner Schad­stof­fe.

JSON-Daten Air Qua­li­ty API

Die für dei­nen Ort gül­ti­gen Koor­di­na­ten kannst du inner­halb der Adres­se aus­tau­schen:

Erläuterung zu JSON

JSON (Java­Script Object Nota­ti­on) dient dem Aus­tausch von Daten zwi­schen einem Ser­ver und einer Web­an­wen­dung. JSON-Daten sind eine Samm­lung von Schlüs­sel-Wert-Paa­ren. Die Biblio­thek fil­tert aus den Roh­da­ten die­se Schlüs­sel-Wert-Paa­re her­aus.

aktu­el­les Wet­ter
Wet­ter­vor­her­sa­ge
links: extra­hier­te Daten zum aktu­el­len Wet­ter im Brow­ser rechts: JSON-Daten zum aktu­el­len Wet­ter

Das Programm

Benötigte Bibliotheken

Bibliotheken und Variable

Du musst die SSID des Rou­ters und das Pass­wort anpas­sen.
Das Pro­gramm ver­wen­det eine sta­ti­sche Adres­se.
Sie macht dich von der auto­ma­ti­schen Adress­ver­ga­be mit­tels DHCP unab­hän­gig, aller­dings musst du her­aus­fin­den, wel­cher Bereich der IP-Adres­sen vom Rou­ter reser­viert wird. Aus die­sem Bereich darfst du kei­ne IP-Adres­se wäh­len.

Bei­spiel Fritz!Box
Tipp
Das Pro­gramm arp (Win­dows) und arp-scan (Linux) lis­tet die IP-Adres­sen auf:
Win­dows: arp -a
Linux: arp-scan -l
arp-scan Aus­ga­be Linux (Aus­schnitt)
  • sta­ti­sche IP-Adres­se
    IPAd­dress ip(192, 168, 1, 120);
  • Gate­way ist der Rou­ter
    IPAd­dress gateway(192, 168, 1, 1);
  • der Rou­ter wird nicht auto­ma­tisch als DNS-Ser­ver ein­ge­bun­den, er muss expl­zit ange­ge­ben wer­den
    IPAd­dress primaryDNS(192, 168, 1, 1);
  • öffent­li­cher sekun­dä­rer DNS-Ser­ver (⤷Quad9) als Back­up
    IPAd­dress secondaryDNS(9, 9, 9, 9);
  • die Unter­schie­de bei der Ein­bin­dung der Biblio­the­ken für die ver­schie­de­nen Mikro­con­trol­ler wer­den mit #ifdef abge­fragt
    #ifdef ESP32
    // ESP32
    #else
    // EP8266
    #endif
  • der ESP8266 kann wegen eines unter­schied­li­chen Auf­rufs der JSON-Abfra­ge kein https ver­wen­den, daher wird dies bei der Adres­se des Open-Meteo-Ser­vers berück­sich­tigt
  • die Varia­ble Info­An­zei­gen schal­tet die Infor­ma­tio­nen zur IP-Adres­se, Rou­ter und Signal­stär­ke ein oder aus

Der setup-Teil

  • Zeit­zo­ne bestim­men
    ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120);
    CEST: Cen­tral Euro­pean Sum­mer­ti­me
    Beginn euro­päi­sche Som­mer­zeit letz­ter Sonn­tag im März 2 Uhr UTC + 2 Stun­den
    CET: Cen­tral Euro­pean Time
    Beginn Nor­mal­zeit letz­ter Sonn­tag im Okto­ber 3 Uhr UTC + 1 Stun­de
    ntp.ruleSTD("CET", Last, Sun, Oct, 3, 60);
  • ntp star­ten
    Zeit­ser­ver deut­scher NTP-Pool
    ntp.begin("de.pool.ntp.org");
  • Web­ser­ver star­ten
    Server.begin();
  • Server.on("/", SeiteBauen);
    Die Funk­ti­on Sei­te­Bau­en() wird auf­ge­ru­fen, wenn die IP-Adres­se im Brow­ser ein­ge­ge­ben oder die Sei­te aktua­li­siert wird.

Der loop-Teil

Der loop-Teil war­tet auf Anfor­de­run­gen der Kli­en­ten, also eines ver­bun­de­nen Web­brow­sers.

Die Funktion SeiteBauen()

  • Wenn der Name der Stadt Umlau­te ent­hält, müs­sen sie für die Anzei­ge umge­wan­delt wer­den:
    ä = ä
    ö = ö
    ü = ü
    ß = ß
    Ä = Ä
    Ö = Ö
    Ü = Ü

Daten für die Luftqualität (AQI)

  • im String Ser­ver­Luft­Da­ten sind die Roh­da­ten ent­hal­ten, sie wer­den mit dese­ria­li­ze­J­son in ein les­ba­res For­mat umge­wan­delt
  • Daten für den CO2-Gehalt, PM2,5 ,die Luft­qua­li­tät und den Ozon­wert extra­hie­ren
    LuftCO2 = String(JSONLuftDaten["hourly"]["carbon_dioxide"][ntp.hours()]);
    LuftQuualitaet = String(JSONLuftDaten["hourly"]["european_aqi"][ntp.hours()]);
    PM2_5 = String(JSONLuftDaten["hourly"]["pm2_5"][ntp.hours()]);
    PM2_5.replace(".", ",");

    Ozon = String(JSONLuftDaten["current"]["ozone"]);
    Ozon.replace(".", ",");

    UV_Index = String(JSONLuftDaten["current"]["uv_index"]);
    UV_Index.replace(".", ",");
  • für die Bewer­tung des AQI, des Ozon­wer­tes, des PM-Wer­tes und des UV-Inde­xes habe ich die Daten des Umwelt­bun­des­am­tes berück­sich­tigt
Quel­le: Umwelt­bun­des­amt
Quel­le: Umwelt­bun­des­amt
Quel­le: Umwelt­bun­des­amt

Wetterdaten

  • der String Ser­ver­Wet­ter ent­hält die Roh­da­ten
  • die aktu­el­len Wet­ter­da­ten, die als float-Varia­ble vor­lie­gen wer­den extra­hiert, auf eine Nach­kom­ma­stel­le gekürzt und der . durch ein , ersetzt (Aus­zug)
    float aktuelleTemperatur = JSONWetter["current"]["temperature_2m"];
    String AnzeigeAktuelleTemperatur = String(aktuelleTemperatur, 1);
    AnzeigeAktuelleTemperatur.replace(".", ",");
  • für alle Wer­te der Vor­her­sa­ge, die im float-For­mat vor­lie­gen wer­den in Arrays jeweils Platz für vier Wer­te und deren Anzei­ge geschaf­fen
    Anmer­kung: Natür­lich wür­den drei Wer­te aus­rei­chen: ich habe mich aber für vier ent­schie­den, damit die Arrays für die extra­hier­ten Wer­te und für die Anzei­ge der Wer­te iden­tisch num­me­riert wer­den kön­nen.
    float TemperaturMax[4];
    float TemperaturMin[4];
    float SummeNiederschlag[4];
    String AnzeigeTemperaturMax[4];
    String AnzeigeTemperaturMin[4];
    String AnzeigeSummeNiederschlag[4];
  • in einem wei­te­ren Schritt wird der . als Dezi­mal­trenn­zei­chen durch ein , ersetzt (Aus­zug)
    AnzeigeTemperaturMax[0] = String(TemperaturMax[0], 1);
    AnzeigeTemperaturMax[0].replace(".", ",");
    AnzeigeTemperaturMin[0] = String(TemperaturMin[0], 1);
    AnzeigeTemperaturMin[0].replace(".", ",");
    AnzeigeSummeNiederschlag[0] = String(SummeNiederschlag[0], 1);
    AnzeigeSummeNiederschlag[0].replace(".", ",");
  • mit der Varia­ble Wet­ter­code kön­nen die Pik­to­gram­me von Open­wea­ther­map zuge­ord­net wer­den
    Die Nut­zung der Icons ist frei (Quel­le: https://openweathermap.org/faq)
  • Extra­hie­ren und Zusam­men­set­zen des Datums
    das Datum liegt im For­mat „2026-09-22“ vor, es muss mit ⇒sub­string neu zusam­men­ge­setzt wer­den
    String(JSONWetter["daily"]["time"][0]).substring(8, String(JSONWetter["daily"]["time"][0]).length()) + "." + String(JSONWetter["daily"]["time"][0]).substring(5, 7) + "." + String(JSONWetter["daily"]["time"][0]).substring(0, 4)
  • die Zeit wird als „2026-09-22T07:17“ dar­ge­stellt, sie muss gekürzt wer­den
    String(JSONWetter["daily"]["sunrise"][0]).substring(11, String(JSONWetter["daily"]["sunrise"][0]).length())
  • Sei­te­Bau­en erstellt die Web­sei­te
    Die Inhal­te wer­den nach und nach dem String Sei­te (+=) hin­zu­ge­fügt.
    Server.send sen­det den String Sei­te im For­mat text/html, wird der Code 200 bestä­tigt, wur­de die Sei­te erfolg­reich über­tra­gen.

Gestaltung der Seite mit CSS

  • für die Gestal­tung wird ein wenig CSS benö­tigt
    Anfüh­rungs­zei­chen müs­sen mit \ „mas­kiert“ wer­den
    <h1 style=\"font-size: 24pt; color: black; background: #e9fdd4;padding: 10px;\">
    Über­schrift h1, Schrift­grö­ße 24 Punk­te, Schrift­far­be schwarz, far­bi­ger Hin­ter­grund, Abstand 10 Punk­te
    <div style=\"height:230px; line-height: 1.6em; display:block\">";

    Höhe, Zei­len­ab­stand und Anzei­ge als Block
    <p style=\"font-size: 14pt\"> </p>
    Schrift­grö­ße des Absat­zes 14 Punk­te

Die Funktion WettercodeAbrufen()

Die Funk­ti­on ermit­telt das Sym­bol und die Beschrei­bung für die Wet­ter­la­ge. Ich habe die Sybo­le in dop­pel­ter Grö­ße ver­wen­det, wenn dir die klei­nen Sym­bo­le lie­ber sind, musst du jeweils das 4x durch 2x erset­zen.

Quellen


Letzte Aktualisierung: Okt. 7, 2026 @ 7:31