Überwachung der Internetgeschwindigkeit mit openHAB

Ich habe hier einen interessanten Artikel über die Überwachung der Interngeschwindigkeit bzw. das „Monitoring“ des Internetproviders gelesen – LINK.

Die Idee wollte ich schon länger für meinen Provider einmal realisieren, hatte aber nie einen vernünftigen Ansatz gesehen.

In dem oben genannten Beispiel / Binding für openHAB wird immer von einer DSL-Verbindung ausgegangen. Bei meinem Glasfaseranschluss ist der DSL-Teil aber deaktiviert:

Aktuell verwende ich das TR064-Binding der FritzBox.

Hat jemand eine Idee wie ich openHAB an einen Glasfaseranschluss anbinden kann?

 

Videos vom Eclipse / openHAB Smart Home Day 2018

Am 21.10.2018 war in Ludwigsburg der Smart Home Day 2018 von Eclipse / openHAB. Wenn Ihr an den Inhalten interessiert seid, findet Ihr hier die Aufzeichnung der Vorträge:

Interessant finde ich an den Videos die Updates im Core-Framework, die MQTT-Integration und der Chat-Bot für openHAB.

Beim HABot handelt es sich um ein Conversational User Interface (CUI) in Kombination mit Machine Learning / Künstlicher Intelligenz und OpenNLP.

Ich denke demnächst werde ich den HABot für openHAB einmal testen und dann hier ausführlich berichten 🙂

 

Stromfresser Internet – Die Schattenseiten der Digitalisierung

Am 23.09.2018 von 16:30 – 17:00 Uhr kam ein interessanter Beitrag zu „Stromfresser Internet – Die Schattenseiten der Digitalisierung“ bei planete im ZDF. Der Inhalt der Sendung wird wie folgt dargestellt:

Es ist smart, es hilft uns, besser zu leben: das Internet. Doch ohne eine gigantische Maschinerie läuft nichts. Unzählige Rechenzentren werden gebraucht – und die sind wahre Stromfresser.

Ihr könnt den Beitrag in der zugehörigen Mediathek ansehen (oder hier direkt in diesem Beitrag). Das Video kann bis zum 20.09.2019 online abgerufen werden.

Der Videobeitrag ist sehr interessant und zeigt einmal ein paar andere Seiten der Digitalisierung auf. Wie ist eure Meinung dazu? Welche Risiken seht Ihr beim Thema „Digitalisierung“?

 

Abbildung „Müllkalender“ in openHAB

Um regelmäßig seine Mülltonnen am Entsorgungstag am Straßenrand zu stellen, haben die meisten Personen einen Papierkalender im Haus. Viele Entsorger stellen aber auch die Abholdaten der Mülltonnen online oder per Kalender bereit

Für den Landkreis Dachau gibt es eine App (DAH-Müll) und eine Oberfläche zur Visualisierung. Leider kann man auf die Daten dort nicht direkt per ICS / iCalendar zugreifen  (da haben sich die Zuständigen etwas sehr gutes einfallen lassen).

Deswegen muss man jetzt manuell einmal die Kalenderdaten pro Jahr dort exportieren und sie in einen eigenen Kalender importieren (geht auch, aber Anwenderfreundlich ist etwas anderes).

Der Anwendungsfall ist also einen Kalender auszulesen und am Vortag eine Erinnerung an die digitalen Endgeräte, Sprachsteuerungen oder Kalender zu senden. Dazu wird in openHAB das CalDAV-Binding verwendet.

Beispiele für die Verwendung findet Ihr hier bei onesmarthome.de oder im openhabforum.de.

Kalendereinrichtung

Im ersten Schritt besorgt man sich die iCalendar-Daten aus seinem jeweiligen Landkreis / Ort. Bei mir waren die Daten hier.

Leider musste ich die Inhalte noch etwas „umformatieren“:

  • DTEND-Tag fehlt in den Kalenderdaten (ohne diese können die Daten nicht in der ownCloud verwendet werden)
  • DTEND-Tag muss einen Tag nach dem DTSTART-Tag gesetzt sein (sonst können die Daten nicht in der ownCloud verwendet werden)

Danach habe ich in meinem System (hier ownCloud) einen Kalender „Müll“ erstellt und die oben beschriebenen Daten importiert.

Danach kann ich folgenden Link für die weitere Integration verwenden:

https://URL/remote.php/dav/calendars/USER/CALENDAR/

Die URL, USER und CALENDAR müsst Ihr an eure Anforderungen anpassen.

Binding

Das CalDAV1-Binding wird wie folgt installiert:

Paper UI – Add-ons – Bindings – CalDAV Binding (personal) – INSTALL

ACHTUNG: Das CalDAV Binding (command) wird zur Steuerung und Präsenzmeldung verwendet und ist für diesen Beitrag nicht notwendig.

Services (caldavio.cfg)

Es wird die Datei services/caldavio mit folgendem Inhalt erstellt:

caldavio:Muell:url=https://URL/remote.php/dav/calendars/USER/CALENDAR/

caldavio:Muell:username=USER

caldavio:Muell:password=PASSWORD

caldavio:Muell:reloadInterval=60

caldavio:Muell:preloadTime=2880

caldavio:Muell:disableCertificateVerification=true

caldavio:Muell:charset=utf8

Die groß geschriebenen Wörter bitte mit euren Daten ergänzen. Wichtig war in meiner Konfiguration noch disableCertificateVerification (wahrscheinlich wegen meinen kostenlosen Zertifikaten) und charset auf UTF-8.

Den reloadInterval kann man zum Testen auch auf 1 Minute stellen.

Items (CalDAV.items)

Ich habe für zwei Kalendereinträge und Datumswerte die Items generiert (es können bei mir zwei Tonnen zum gleichen Tag abgeholt werden):

/* Müllkalender */
String      CalDAV_Muell_1       "Erste Tonne [%s]"                          <calendar>    { caldavPersonal="calendar:Muell type:EVENT eventNr:1 value:NAME" }
DateTime    CalDAV_Muell_1_Date  "Datum der Abholung [%1$td.%1$tm.%1$tY]"    <calendar>    { caldavPersonal="calendar:Muell type:EVENT eventNr:1 value:START" }
String      CalDAV_Muell_2       "Zweite Tonne [%s]"                         <calendar>    { caldavPersonal="calendar:Muell type:EVENT eventNr:2 value:NAME" }
DateTime    CalDAV_Muell_2_Date  "Datum der Abholung [%1$td.%1$tm.%1$tY]"    <calendar>    { caldavPersonal="calendar:Muell type:EVENT eventNr:2 value:START" }

Sitemap

In der Sitemap habe ich das recht einfach so dargestellt:

Frame label="Informationen" {
Frame label="Müllkalender"{
                           Text item=CalDAV_Muell_1
                           Text item=CalDAV_Muell_1_Date
                           Text item=CalDAV_Muell_2
                           Text item=CalDAV_Muell_2_Date
              }
}

Rules (CalDAV.rules)

Nun erfolgt die Automatisierung und die Benachrichtigung in der Regel (das kann man bestimmt noch etwas eleganter „scripten“):

rule "Müllkalender"
when
//Time cron "0 * * ? * *"    //every 1 Minute
    Time cron "0 15 17 * * ?"    //once per Day 17:15
    //Item date_today changed
then
    var String muelltonne_1
    muelltonne_1 = CalDAV_Muell_1.state.toString

    var String muelltonne_2
    muelltonne_2 = CalDAV_Muell_2.state.toString

    // Prüfung ob der Wert gefüllt ist (damit beim cast auf DateTimeType keine Fehlermeldung erscheint)
    if (muelltonne_1 != "UNDEF") {
        // Datum der Abholung wird mit dem aktuellen Datum verglichen
        // die erste Bedingung prüft, ob das aktuelle Datum vor dem Ablaufdatum + 24 Std. liegt
        // die zweite Bedingung prüft, ob das aktuelle Datum nach dem Datum der Abholung liegt
        if (now.isBefore(new DateTime((CalDAV_Muell_1_Date.state as DateTimeType).getCalendar().getTime()).plusHours(24)) &&
            now.isAfter(new DateTime((CalDAV_Muell_1_Date.state as DateTimeType).getCalendar().getTime()))) {

            // Benachrichtigung per Telegram an Bot senden
            if(muelltonne_2 == "UNDEF") {
                sendTelegram("xxx_bot", "Müllkalender: %s", muelltonne_1)
                logInfo("INFO","CalDAV.rules - Müllkalender: %s", muelltonne_1)           
            } else {
                sendTelegram("xxx_bot", "Müllkalender: %s & %s", muelltonne_1, muelltonne_2)
                logInfo("INFO","CalDAV.rules - Müllkalender: %s & %s", muelltonne_1, muelltonne_2)           
            }         
        }
    }
end

Fazit

Die Anbindung des Kalenders in openHAB war relativ einfach. Etwas schwieriger hat sich die Anpassung der ICS-Datei aus meinem Landkreis gestaltet. Danach hat man recht einfach (nach ein paar Tests) seine Kalenderdaten angebunden.

In der Regel waren dann noch ein paar Workarounds notwendig, aber dann waren die Daten auch richtig vorhanden. Die Konvertierung in UTF-8 / Unicode war nicht so einfach in der cfg zu finden. Auch den CRON-Job nur einmal am Tag zu einer bestimmten Zeit auszuführen war für einen „Nicht-UNIXer“ nicht das einfachste 😉

Nun bekomme ich aber am Vortag um 17:15 Uhr eine Information per Telegram, dass die Müllabfuhr am nächsten Tag kommt.

Habt Ihr noch Ideen für die weitere Anbindung von Kalenderdaten? Habt Ihr eine Präsenzmeldung oder Steuerung eures SmartHome damit realisiert?

Aktuelle Zeit und Datum in openHAB per NTP

Für Berechnungen und zur allgemeinen Visualisierung soll in openHAB das aktuelle Datum und Uhrzeit über NTP aktualisiert und dargestellt werden. Weitere Informationen über das Network Time Protocol findet Ihr bei Wikipedia.

Binding

Die Dokumentation zum NTP-Binding findet Ihr hier – https://docs.openhab.org/addons/bindings/ntp/readme.html

Die Installation in der Paper UI wird über „Add-ons – Bindings – NTP Binding – INSTALL“ vorgenommen.

Things (NTP.things)

Eine Konfiguration des Servers wird in der Things-Datei konfiguriert:

ntp:ntp:zeit  [ hostname="nl.pool.ntp.org", refreshInterval=60, refreshNtp=30 ]

Items (NTP.items)

Das Format wird in der Items-Datei den Wünschen entsprechend angepasst:

DateTime Date  "Date [%1$tA, %1$td.%1$tm.%1$tY %1$tH:%1$tM]"  { channel="ntp:ntp:zeit:dateTime" }

Fazit

Mit ein paar Klicks hat man das Zeitprotokoll (NTP) in openHAB integriert.

Eine Visualisierung in der Sitemap ist nicht notwendig, da ich in meinem Fall die Werte nur in Regeln benötige.

In den nächsten Beiträgen werden ich darstellen, für was ich die NTP-Daten benötige.

Unwetterdaten vom DWD in openHAB

Da wir letzte Woche an einem Abend ein größeres Unwetter hatten, habe ich mich entschlossen Unwetterdaten vom Deutschen Wetterdienst in openHAB zu integrieren.

Die Daten vom DWD sollen in der GUI angezeigt werden und wenn ein Unwetter im Anmarsch ist eine Benachrichtigung auf ein mobiles Endgerät senden.

Ein gutes Beispiel wie man die JSON-Daten in openHAB übernimmt, findet Ihr hier im openHAB-Forum.

Vorbereitung

Für die Integration der Unwettermeldungen benötigt Ihr deine „WARNCELLID“ für euren Ort.

Außerdem müssen / können noch bestimmte Bilder für die Visualisierung integriert werden (die Images findet Ihr auch in dem oben genannten Forums-Beitrag):

  • Images nach /icons/classic kopieren
  • Dauert eine Zeit bis diese in der Paper UI dargestellt werden
  • Option: Paper UI – Configuration – Services – UI – Basic UI / Classic UI – Icon Format von „Vecotr“ auf „Bitmap“ stellen (Standard: Vector)
  • Rechte und User in Linux kontrollieren (chmod + chown) – /etc/openhab2/icons/classic

Bindings

Diese Bindings benötigt Ihr für die Integration:

  • Paper UI – Add-ons – Transformations – Javascript Transformation (Version 2.3.0) – INSTALL
  • Paper UI – Add-ons – Transformations – JSONPath Transformation (Version 2.3.0) – INSTALL
  • Paper UI – Add-ons – Transformations – Map Transformation (Version 2.3.0) (war bereits installiert)

Items (Wetter_DWD.items)

Diese Items habe ich für die Visualisierung erstellt:

DateTime        DWD_Warnung_start                   "von: [%1$td.%1$tm.%1$tY %1$tH:%1$tM Uhr]"        <time>                        
DateTime        DWD_Warnung_end                     "bis: [%1$td.%1$tm.%1$tY %1$tH:%1$tM Uhr]"        <time>
Number          DWD_Warnung_level                   "Warnstufe: [MAP(Wetter_DWD.map):%s]"             <dwdwarnung>
String          DWD_Warnung_description             "Beschreibung: [%s]"                              <warnung>
String          DWD_Warnung_headline                "Betreff: [%s]"                                   <warnung>
String          DWD_Warnung_instruction             "Hinweis: [%s]"                                   <warnung>
String          DWD_Warnung_event                   "Event: [%s]"                                     <warnung>

String          DWDSelectedSite

Map (Wetter_DWD.map)

Für die Darstellung muss eine Map erstellt werden:

0=Keine Warnung (0)

1=Wetterwarnung (1)

2=markantes Wetter (2)

3=Unwetterwarnung (3)

4=extremes Unwetter (4)

10=Hitzewarnung (10)

Transform (Wetter_DWD_getWarningsJSON.js)

Die Transformaton der Wetterdaten wird mit diesem Script durchgeführt:

(function(jsonString) {
    var newString = jsonString.replace('warnWetter.loadWarnings(','');
    newString = newString.replace(');','');
    var newJSON = JSON.parse(newString);
    var jsonResult = "";
    if (newJSON.warnings.hasOwnProperty('WARNCELLIC')) {
        jsonResult =JSON.stringify(newJSON.warnings['WARNCELLID'][0]);
    } else jsonResult = 'NULL'
    return jsonResult;
    })(input)

ACHTUNG: Die WARNCELLID muss durch eure individuelle ID ersetzt werden.

Rules (Wetter_DWD.rules)

Für die Automatisierung wird noch folgende Regel erstellt:

rule "DWD Warnungen"
when
Time cron "0 */30 * ? * *"  //every 30 Minutes
//Time cron "0 * * ? * *"    //every 1 Minute

then
var String jsonString = sendHttpGetRequest("https://www.dwd.de/DWD/warnungen/warnapp/json/warnings.json")
var String newString = transform("JS", "Wetter_DWD_getWarningsJSON.js", jsonString)
if (newString !="NULL") {
var String newStart = transform("JSONPATH", "$.start", newString)
var DateTime timestart = new DateTime(Long::parseLong(newStart))
DWD_Warnung_start.postUpdate(new DateTimeType(timestart.toString))
var String newEnd = transform("JSONPATH", "$.end", newString)
if (newEnd !==null) {
var DateTime timeend = new DateTime(Long::parseLong(newEnd))
DWD_Warnung_end.postUpdate(new DateTimeType(timeend.toString))
}

DWD_Warnung_level.postUpdate(transform("JSONPATH","$.level",newString))
DWD_Warnung_description.postUpdate(transform("JSONPATH","$.description",newString))
DWD_Warnung_headline.postUpdate(transform("JSONPATH","$.headline",newString))
DWD_Warnung_instruction.postUpdate(transform("JSONPATH","$.instruction",newString))
DWD_Warnung_event.postUpdate(transform("JSONPATH","$.event",newString))

// Benachrichtigung per Telegram an Bot senden
sendTelegram("BOTNAME", "Wetterwarnung in Altomünster" + "\n" +
                                    "\nWarnstufe: " + DWD_Warnung_level.state.toString +
                                    "\nBeschreibung: " + DWD_Warnung_description.state.toString +
                                    "\nBetreff: " + DWD_Warnung_headline.state.toString +
                                    "\nHinweis: " + DWD_Warnung_instruction.state.toString +
                                    "\nEvent: " + DWD_Warnung_event.state.toString)
}

if (newString =="NULL") {
DWD_Warnung_start.postUpdate("NULL")
DWD_Warnung_end.postUpdate("NULL")
DWD_Warnung_level.postUpdate(0)
DWD_Warnung_description.postUpdate("-")
DWD_Warnung_headline.postUpdate("derzeit keine Warnungen")
DWD_Warnung_instruction.postUpdate("-")
DWD_Warnung_event.postUpdate("-")        
}
end

ACHTUNG: Die Regel wird alle 30 Minuten ausgeführt und aktualisiert so die Daten. Die Funktion sendTelegram sendet an meinen Telegram-Bot die Informationen für die Benachrichtigung auf dem SmartPhone (dieses müsst Ihr dann ggf. hinzufügen oder die Zeilen entfernen – der BOTNAME muss gegen eure Konfiguration getauscht werden).

Sitemap

In der Sitemap können die Inhalte so angezeigt werden:

Text label=“Wetterwarnungen“ icon=“dwdicon“ {

Frame label=““ {

Selection item=DWDSelectedSite label=“Wetter“ icon=“dwd“ mappings=[1=“Aktuell“, 2=“Regenradar“, 3=“Heute“, 4=“Morgen“, 5=“Übermorgen“, 6=“Unwetter“, 7=“Pollenflug“, 8=“Warnungen“]

}

Frame label=“ “        visibility=[DWDSelectedSite==8] {

Text item=DWD_Warnung_headline                label=““                                                                                                        valuecolor=[DWD_Warnung_level==1=“#ffff00″, DWD_Warnung_level==2=“#ffa500″, DWD_Warnung_level==3=“#ff0000″, DWD_Warnung_level==4=“#800000″]

Text item=DWD_Warnung_level                                                        visibility=[DWD_Warnung_level!=0]                        valuecolor=[1=“#ffff00″, 2=“#ffa500″, 3=“#ff0000″, 4=“#800000″]

Text item=DWD_Warnung_start                                                        visibility=[DWD_Warnung_start!=“NULL“]

Text item=DWD_Warnung_end                        icon=“null“                visibility=[DWD_Warnung_end!=“NULL“]

}

Frame label=“ “         visibility=[DWDSelectedSite==8] {

Text item=DWD_Warnung_description                                        visibility=[DWD_Warnung_description!=“-„]

Text item=DWD_Warnung_instruction        icon=“null“                visibility=[DWD_Warnung_instruction!=“-„]

}

Frame label=“ “         visibility=[DWDSelectedSite==8] {

Text item=DWD_Warnung_event                                                        visibility=[DWD_Warnung_event!=“-„]                        valuecolor=[DWD_Warnung_level==1=“#ffff00″, DWD_Warnung_level==2=“#ffa500″, DWD_Warnung_level==3=“#ff0000″, DWD_Warnung_level==4=“#800000“]

}

}

Test

Für einen ersten Test könnt Ihr die DWD-URL manuell aufrufen:

  • https://www.dwd.de/DWD/warnungen/warnapp/json/warnings.json

Bei dieser URL könnt Ihr dann eine WARNCELLID kopieren und in euer Script (JS) einbauen. Damit könnt Ihr dann eine „Warnung“ simulieren und die oben genannten Konfigurationen testen.

Fazit

Im Zusammenspiel mit den mobilen Benachrichtigungen und dem Auslesen der Daten des Deutschen Wetterdienstes ergeben sich sinnvolle Anwendungsbeispiele. Wenn man etwas tiefer in openHAB einsteigen möchte (und es keine Standard-Bindings für die Anforderung gibt) kann man mit dem JSON-Binding und dem JavaScript-Binding recht einfach Webservices anbinden.

Das Auslesen der JSON-Datei klappt recht einfach und ist mit wenigen Zeilen Scripting erledigt.

Würdet Ihr Unwetterdaten in eure SmartHome-Umgebung integrieren? Fallen euch noch weitere Szenarien z.B. Pollenflug etc. ein?

Speicherung von Daten in openHAB

In den letzten Blog-Artikeln habe ich ein paar Wetterdaten in openHAB integriert und diese Daten entsprechend visualisiert.

In diesem Artikel sollen jetzt Daten aus dem WetherBinding von ForecastIo langristig im System gespeichert werden. Dazu wird die Round-Robin-Datenbank RRD4j verwendet.

Die Idee zur Speicherung der Daten ist mir beim Lesen des Beitrags auf  zukunftathome.de gekommen.

Es soll die erfasste Außentemperatur einmal am Tag gespeichert und in einem Diagramm visualisiert werden.

ACHTUNG: RRD4j ist nicht für die langfristige Datenspeicherung geeignet, da ältere Werte immer weniger verfügbar sind.

Installation

Die Installation erfolgt ganz einfach über die Paper UI:

  • Add-ons – Persitence – RRD4j Persistence

Dort die Schaltfläche INSTALL auswählen und die Persistenzschicht ist installiert.

Konfiguration

Mit einem beliebigen Editor (bei mir Visual Studio Code) die Datei rrd4j.persist im Ordner persistence mit folgendem Inhalt anlegen:

Strategies
{
   everyMinute  : "0 * * * * ?"
   everyHour    : "0 0 * * * ?"
   everyDay     : "0 0 0 * * ?"
   default = everyChange
}

Items
{
    weatherTemperature : strategy = everyDay, restoreOnStartup
}

In den Strategies wird definiert in welchen Zeitinverallen Daten abgespeichert werden. Die Strategie für everyMinute muss zwingend angelegt werden.

Unter Items werden die Daten hinterlegt die in der Datenbank gespeichert werden sollen.  Die Daten müssen in den zugehörigen *.items-Dateien vorhanden sein.

In meinem Beispiel wird einmal am Tag die Variable weatherTemperature (also meine Außentemperatur) gespeichert.

Items

In den zugehörigen Items-Dateien muss normalerweise nichts angepasst werden.

Es wird aber eine Hilfsvariable für die Darstellung des Zeitraums in einem Diagramm benötigt:

Number Chart_Zeitraum_D_W_M_Y

Sitemap

Für die Visualisierung können die Daten dann wie folgt eingebunden werden:

Frame label=“Historie Außentemperatur (Altomünster)“ {

Switch item=Chart_Zeitraum_D_W_M_Y label=““ mappings=[0=“Tag“, 1=“Woche“, 2=“Monat“, 3=“Jahr“]

Chart item=weatherTemperature period=D refresh=60000 visibility=[Chart_Zeitraum_D_W_M_Y==0, Chart_Zeitraum_D_W_M_Y==“Uninitialized“]

Chart item=weatherTemperature period=W refresh=60000 visibility=[Chart_Zeitraum_D_W_M_Y==1]

Chart item=weatherTemperature period=M refresh=60000 visibility=[Chart_Zeitraum_D_W_M_Y==2]

Chart item=weatherTemperature period=Y refresh=60000 visibility=[Chart_Zeitraum_D_W_M_Y==3]

}

Funktionstest

Da ich momentan die Daten nur einmal am Tag speichere, wollte ich auch sehen ob etwas in den RRD4j-Datenbanken ankommt.

Dazu kann die REST-API wie folgt aufgerufen werden – http://IP:PORT/doc/index.html

Mit dieser URL kann ein Item aus der Persistenzschicht abgerufen werden (hier weatherTemperature):

http://IP:PORT/rest/persistence/items/weatherTemperature

Als Ergebnis sollte dann eine Struktur wie hier dargestellt werden:

{„name“:“weatherTemperature“,“datapoints“:“1″,“data“:[{„time“:1535463840000,“state“:“24.64999999999999857891452847979962825775146484375″}]}

Fazit

Mit ein paar Handgriffen kann man seine openHAB-Daten in einer Datenbank ablegen. Für einen ersten Test sollte RRD4j für meine Anforderungen ausreichen (eine langfristige Speicherung der Wetterdaten werde ich erst mit einer eigenen Wetterstation umsetzen).

Welche Daten würdet Ihr langfristig aus eurem System speichern? Habt Ihr andere Datenbanken verwendet?

Wetterprognosen in openHAB

Ich hatte in einem vorherigen Beitrag schon einmal dargestellt wie man Wetter-Daten in openHAB visualisieren kann. Hier hatte ich das Problem, dass ich über den Provider keine Wetterprognosen über die kostenlose API bekommen habe.

Ich habe jetzt ein paar Provider verglichen und mich für einen entschieden:

  • WeatherUnderground (keine kostenlose API für den Privatgebrauch)
  • OpenWeatherMap (keine Wetterprognosen da nur Premium-Key unterstützt wird, gute Möglichkeit für aktuelle Daten)
  • Wunderground (keine kostenlose API für den Privatgebrauch)
  • ForecastIo (kostenlose API, Wetterprognose funktioniert, 1000 Aufrufe pro Tag)

Die meisten meiner Anforderungen erfüllt ForcastIo momentan. Ich habe den Provider jetzt für den ersten Test eingebunden und werde die aktuellen Wetterdaten und Prognosen die nächsten Tage mit dem echten Wetter vergleichen.

Welchen Wetterprovider nutzt Ihr für eure Wetterdaten?