FHEM Tutorial-Reihe - Part 42: Regenradar integrieren

Mit ** gekennzeichne Links auf dieser Seite sind Affiliatelinks.

Einer meiner meist genutzen Smartphone-Apps ist Regenradar. Dort sieht man nicht nur ob es gerade regnet, sondern kann auch abschätzen wann es aufhört oder zu regnen beginnt. Gerade wenn ich eine längere Runde mit dem Hund plane, hat mich das schon oft vor dem Regen bewahrt.

Was wird benötigt?

  • Eine FHEM-Installation

Video

FHEM-Kurs

Befehle

Angefangen habe ich mit dem einfachsten Fall: Einem Bild über einen weblink. Da es sich um ein animiertes gif handelt, muss man hier nichts weiter tun.

define OUT_RegenRadar weblink image http://images2.wetterdienst.de/maps/radar/Radarfilm_West.gif

Doch das war mir nicht schön genug. Ich wollte mehr! Also habe ich mich hingesetzt, und eine eigene Funktion geschrieben, welche die URL von WetterOnline zusammenbaut. Hier haben wir verschiedene Platzhalter, welche durch Jahr, Monat, Tag, Stunde und Minute ersetzt werden müssen. Die Schwierigkeit hierbei war, dass man natürlich nur 5-Minuten-Abstände realisieren darf. Ein bild zu 12:34 oder 15:18 existiert also nicht.

define OUT_RegenRadarNRW weblinkt htmlCode {regenRadarHtml()}
sub regenRadarHtml() {
    my $now = DateTime->now();

    return sprintf(
        '<img src="https://www.wetteronline.de/?pid=p_radar_map&ireq=true&src=wmapsextract/vermarktung/global2maps/%d/%02d/%02d/NRW/grey_flat/%d%02d%02d%02d%02d_NRW.png"; />',
        $now->year(),
        $now->month(),
        $now->day(),
        $now->year(),
        $now->month(),
        $now->day(),
        $now->hour(),
        floor($now->minute() / 5) * 5
    );
}

Dann wurde der Code immer weiter ausgebaut (wie im Video zu sehen). Dabei habe ich festgestellt, dass für die Zukunft (also die eigentliche Prognose) andere URLs zu den Bildern genutzt werden müssen. Weiterhin kann man nun noch einen diff als Parameter übergeben. Das sieht in meinem Fall so aus, dass man hier z.B. -10 schreiben kann (Regenradar von vor 10 Minuten), 0 für jetzt gerade übergeben kann oder auch positive Werte für eine Prognose holen kann.

sub regenRadarHtml($) {
    my ($diff) = @_;

    my $now = DateTime->now()->add(minutes => (floor($diff / 5) * 5));
    my $minute = (floor($now->minute() / 5) * 5);

    if ($diff <= 0) {
        return sprintf(
            '<img src="https://www.wetteronline.de/?pid=p_radar_map&ireq=true&src=wmapsextract/vermarktung/global2maps/%d/%02d/%02d/NRW/grey_flat/%d%02d%02d%02d%02d_NRW.png"; />',
            $now->year(),
            $now->month(),
            $now->day(),
            $now->year(),
            $now->month(),
            $now->day(),
            $now->hour(),
            $minute
        );
    } else {
        return sprintf(
            '<img src="https://www.wetteronline.de/?pid=p_radar_map&ireq=true&src=wmapsextract/vermarktung/prog2maps/short_range/%d/%02d/%02d/NRW/grey_flat/%d%02d%02d%02d%02d_NRW.png"; />',
            $now->year(),
            $now->month(),
            $now->day(),
            $now->year(),
            $now->month(),
            $now->day(),
            $now->hour(),
            $minute
        );
    }
}

Aber da ich eine Animation wollte (wie in den Apps), habe ich noch ein wenig ergänzt. Jetzt werden mehrere Bilder nacheinander geladen und in einen Container gepackt. Den Rest erledigt dann JavaScript (bisher noch etwas unsauber gelöst). Dazu werden dann alle Bilder versteckt, mit Nummern versehen und nacheinander mit einem Interval von einer Sekunde dargestellt. Ziemlich einfach, aber auch längst nicht perfekt.

Wie gesagt habe ich schon überlegt, ob es nicht Sinn macht daraus eine FHEM-Extension zu machen. Dann könnte man einfach die Region übergeben und der Rest läuft dann vollautomatisch ab. Noch cooler wäre es natürlich, wenn man die Bilder analysieren könnte um zu ermitteln ob es bald anfängt zu regnen. Und vor allem wann. Finde ich sehr spannend. Schreibt doch einfach mal was ihr davon haltet.

sub regenRadarHtml($) {
    my ($diff) = @_;

    my $now = DateTime->now()->add(minutes => (floor($diff / 5) * 5));
    my $minute = (floor($now->minute() / 5) * 5);

    if ($diff <= 0) {
        return sprintf(
            '<img class="image-slide" src="https://www.wetteronline.de/?pid=p_radar_map&ireq=true&src=wmapsextract/vermarktung/global2maps/%d/%02d/%02d/NRW/grey_flat/%d%02d%02d%02d%02d_NRW.png"; />',
            $now->year(),
            $now->month(),
            $now->day(),
            $now->year(),
            $now->month(),
            $now->day(),
            $now->hour(),
            $minute
        );
    } else {
        return sprintf(
            '<img class="image-slide" src="https://www.wetteronline.de/?pid=p_radar_map&ireq=true&src=wmapsextract/vermarktung/prog2maps/short_range/%d/%02d/%02d/NRW/grey_flat/%d%02d%02d%02d%02d_NRW.png"; />',
            $now->year(),
            $now->month(),
            $now->day(),
            $now->year(),
            $now->month(),
            $now->day(),
            $now->hour(),
            $minute
        );
    }
}

sub regenRadarMultipleHtml($$) {
    my ($diff, $count) = @_;
    my $ident = 'slider-' . int(rand(100));

    my $ret = '';

    for (my $i = 0; $i <= $count * 5; $i += 5) {
        $ret .= regenRadarHtml($diff + $i);
    }

    return '
    <script type="text/javascript">
        jQuery(document).ready(function ($) {
            // Image Slider
            $("#' . $ident . ' .image-slide").each(function(index) {
                $(this).attr("data-index", index);
                if (index > 0) {
                    $(this).hide();
                } else {
                    $(this).addClass("current");
                }
            });

            setInterval(
                function() {
                    var nextSlideId = parseInt($("#' . $ident . ' .image-slide.current").attr("data-index")) + 1;

                    var nextSlide = $("#' . $ident . ' .image-slide[data-index=" + nextSlideId + "]");

                    if (nextSlide.length == 0) {
                        nextSlide = $("#' . $ident . ' .image-slide[data-index=0]");
                    }

                    $("#' . $ident . ' .image-slide").each(function(index) {
                        $(this).removeClass("current");
                        $(this).hide();
                    });

                    nextSlide.show();
                    nextSlide.addClass("current");
                },
                1000
            );
        });
    </script>
    <div class="image-slides" id="' . $ident . '">' . $ret . '</div>';
}

Zusätzlich kann man auch noch ein Modul der Unwetterzentrale nutzen. Hier bekommt man aber nur Infos, ob gerade schlimmere Dinge bevorstehen. Also Regen gehört nicht dazu soweit ich weiß (nur Starkregen - Unwetter eben). Dies habe ich aus dem Video wieder rausgeschnitten, weil es nicht sonderlich spektakulär ist.

define OUT_Unwetterzentrale UWZ DE 33102 300

define OUT_UnwetterzentraleDetailiert weblink htmlCode {UWZAsHtml("OUT_Unwetterzentrale")}
define OUT_UnwetterzentraleKarteLand weblink htmlCode {UWZAsHtmlKarteLand("OUT_Unwetterzentrale", "nordrhein-westfalen")}
define OUT_UnwetterzentraleKarteMovie weblink htmlCode {UWZAsHtmlMovie("OUT_Unwetterzentrale", "niederschlag-wolken-de")}

Newsletter

Trage Dich jetzt in den Newsletter ein und genieße dadurch viele Vorteile:

  • 5€-Gutschein als Dankeschön
  • Zugang zu exklusiven Inhalten
  • Rabattaktionen für Kurse
  • Angebote für Produkte

* Durch Angabe meiner E-Mail-Adresse erkläre ich mich damit einverstanden, dass mir regelmäßig Informationen und Produktempfehlungen aus dem Fachgebiet Smart Home zugesendet werden. Mit dem Eintrag akzeptieren Sie unsere Datenschutzbestimmungen. Meine Einwilligung kann ich jederzeit widerrufen.

Matthias Kleine

Matthias Kleine

Großer Fan und Anhänger von OpenSource-Projekten und erweiterbaren Haus-Automatisierungskomponenten. Je offener und flexibler das System, desto besser. Ich lege mich ungern auf einzelne Protokolle oder Standards fest, sondern probiere aus allen Welten das Beste zu verheiraten. Unterwegs als Softwareentwickler, Trainer und Blogger im Bereich Smart Home.

Auf YouTube und hier im Blog gibt es bereits unzählige kostenlose Videos, Informationen und Tutorials. Wenn Dir das noch nicht reicht, ist ein Training genau das richtige für Dich! Die folgenden Trainings haben den Vorteil, dass immer von Anfang an gestartet wird und Du ohne Vorwissen teilnehmen kannst.