FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: Heiner am 23 Oktober 2024, 20:19:42

Titel: Weblink mit dynamsicher URL
Beitrag von: Heiner am 23 Oktober 2024, 20:19:42
Hallo,

Ich moechte gern in fhem ein aktuelles Webcam Bild einer fremden Webseite einbinden.
Das ist im Prinzip einfach z.B. so:
define Kluesserathcam weblink image https://api.holfuy.com/cam/s242.jpg
Nun habe ich eine andere WebcamQuelle die leider eine dynamische Zuweisung hat sprich der Dateiname der letzten aufnahme aendert sich staendig.

die Idee waere nun (nonblocking get zu nutzen um die aktuelle Adresse zu erhalten (Danke TomLee), aber wie genau?

define Zeltingencam weblink image { HttpUtils_NonblockingGet( { url=>"http://www.moselfalken.de/zeltingen-rachtig/img.img-fluid", callback=>sub($$$) { my ($hash, $err, $data) = @_;; Log 1, "$err/$data" } }) }

klappt aber natuerlich nicht, ich habe auch nur geraten was die Suche auf der Webseite angeht.

und vermutlich noch mehr nicht stimmt.

Kann jemand helfen?

Titel: Aw: Weblink mit dynamsicher URL
Beitrag von: TomLee am 23 Oktober 2024, 21:44:53
Hallo,

ZitatKann jemand helfen?

Beim Verständnis helfen wenn genaue Fragen sind gerne, aber hier nen halben Roman schreiben und alles kurz und knapp erklären liegt mir nicht.

Ich hab mir darüber Gedanken gemacht.
Wie ich vorgeschlagen habe, es im htmlCode-"Modus" mit HttpUtils_NonblockingGet zu versuchen, bekomme ich selbst nicht "vernünftig" hin. Die Rückgabe des callback direkt verwenden ist mein/das Problem ? Dazu hab ich evtl. zu wenig bisher verstanden.

Wenn es wie im anderen Thread auch, darum geht, das Bild im Dashboard anzuzeigen hab ich mir eine Lösung mit einer einfachen at-Definition überlegt. Damit wird allerdings der Devicename der Definition links vom Bild im Dashboard angezeigt, vmtl. wolltest Du ja gerade deswegen die weblink-Variante weil dort nur das Bild gezeigt wird ?


Die auskommentierte Variante holt zwar immer die Daten neu, schreibt das Reading aber nur bei Änderung.
Die aktive Variante, mit attr,  wird alle Zeit x ausgeführt, mit silent bekommt man davon aber nix mit.
Bei beiden Varianten aktualisiert sich das Bild in der Raumansicht bei Änderung automatisch, der einzige Unterschied zu weblink ist das der Devicename links neben dem Bild steht.
Zitatdefmod at_test at +*00:00:30 {\
HttpUtils_NonblockingGet({\
url=>'https://www.moselfalken.de/zeltingen-rachtig',\
callback=>sub($$$){\
    my $hash = $defs{$SELF};;\
    return readingsSingleUpdate($hash, "picname", "Fehler: $_[1]", 1) if($_[1]);;\
    my $ret = $_[2];;\
    $ret =~ m,.*(\w+.\w+.csm_camimg_\d{6}_\d{6}_\w+\.jpg)..width="930".height="697".title="".alt="">,s;;\
    #$ret = qq(<img width="720" height="480" style="border: 2px solid red;;border-radius: 10px;;" src="https://www.moselfalken.de/fileadmin/_processed_/$1">);;\
    #readingsBeginUpdate($hash);;\
    #readingsBulkUpdateIfChanged($hash,'html',$ret);;\
    #readingsEndUpdate($hash,0);;\
    fhem("attr -silent $SELF stateFormat <img width='720' height='480' style='border: 2px solid red;;;;border-radius: 10px;;;;' src='https://www.moselfalken.de/fileadmin/_processed_/$1'>");;\
}
})
}
attr at_test group Dash
attr at_test stateFormat <img width='720' height='480' style='border: 2px solid red;;border-radius: 10px;;' src='https://www.moselfalken.de/fileadmin/_processed_/8/b/csm_camimg_241023_182239_7d57bfe018.jpg'>

setstate at_test <img width='720' height='480' style='border: 2px solid red;;border-radius: 10px;;' src='https://www.moselfalken.de/fileadmin/_processed_/8/b/csm_camimg_241023_182239_7d57bfe018.jpg'>
setstate at_test 2024-10-23 17:20:39 html <img width="720" height="480" style="border: 2px solid red;;border-radius: 10px;;" src="https://www.moselfalken.de/fileadmin/_processed_/8/8/csm_camimg_241023_171706_618bf35dd0.jpg">
setstate at_test 2024-10-23 21:30:25 state Next: 21:30:55


edit:

Bei der ersten Variante muss man stateFormat dann so definieren:
attr at_test stateFormat {ReadingsVal($name,'html','')}


Titel: Aw: Weblink mit dynamsicher URL
Beitrag von: Heiner am 24 Oktober 2024, 13:11:06
wau, super vielen Dank. Ich brauch ein bischne bis ich alles verstehe

du hast nun 2 Varianten mit At gebaut

die aktive mit regelmaessigem update des Readings
die auskomentierte die das Reading nur updated wenn eine Aenderung vorliegt

Ist somit nicht die 2te die eigentlich elgantere und inteligentere das sie das Reading nicht unnoetig ueberschriebt solange sich nix aendert - oder gibts einen Grund die andere Variante zu bevorzugen?

Der Filter ueber die bildgroesse  hinter dem link ist genial, ich hab mich die ganze Zeit auch gefragt auf was ich filtern koennte da ich den html code der url sehr schwierig fand.

"Weblink" oder "at" ist ein kleiner Neben-aspekt, aber ja nur das Bild waere noch schoener. Hier bin ich zuversichtlich selbst eine Loesung zu finden

Nochmals vielen Dank.
Titel: Aw: Weblink mit dynamsicher URL
Beitrag von: TomLee am 24 Oktober 2024, 17:11:53
ZitatHier bin ich zuversichtlich selbst eine Loesung zu finden
Ich meine so einfach ist das nicht und man müsste dazu dann im jeweiligen Modulcode eingreifen, weiß es aber nicht.

Und weil es vermutlich nicht so einfach ist, kam mir der Gedanke auf ob das überhaupt sein muss die Abfrage nicht blockierend auszuführen ? Ich vermute nicht.

Das wäre dann problemlos in dem weblink umzusetzen:

defmod wl_test weblink htmlCode {\
my $ret = GetFileFromURL("https://www.moselfalken.de/zeltingen-rachtig");;\
return if !$ret;;\
$ret =~ m,.*(\w+.\w+.csm_camimg_\d{6}_\d{6}_\w+\.jpg)..width="930".height="697".title="".alt="">,s;;\
return qq(<img width="720" height="480" style="border: 2px solid red;;border-radius: 10px;;" src="https://www.moselfalken.de/fileadmin/_processed_/$1">);;\
}

setstate wl_test initialized

aber das automatisch das aktuelle Bild angezeigt wird, ist hier halt ohne die Seite zu aktualisieren nicht
Titel: Aw: Weblink mit dynamsicher URL
Beitrag von: Heiner am 24 Oktober 2024, 20:22:50
Hi,

perfekt, funktioniert super. Besten Dank :)
Titel: Aw: Weblink mit dynamsicher URL
Beitrag von: Torxgewinde am 26 Oktober 2024, 06:23:14
Guck dir vielleicht auch dies hier mal an, ein HTTPMOD genügt dafür eigentlich. Als Test habe ich es auf Cooltux Demoserver (https://demo-fhem.cooltux.net/fhem?detail=PM&fw_id=#) erstellt:


Da das Userreading "bild" ein Reading ist, kümmert sich FHEMWEB darum es zu aktualisieren, wenn ein Event zu dem Reading ausgelöst wurde. Damit dies nicht unnötigerweise passiert ist event-on-change-reading gesetzt.

defmod PM HTTPMOD https://www.moselfalken.de/zeltingen-rachtig 600
attr PM reading01Name WebcamURL
attr PM reading01Regex (fileadmin\/_processed_\/\w+\/\w+\/csm_camimg_\d{6}_\d{6}_\w+\.jpg)
attr PM room Experimente
attr PM event-on-change-reading .*
attr PM stateFormat bild
attr PM userReadings bild:WebcamURL:.* {\
    my $URL = "https://www.moselfalken.de/". ReadingsVal($name, "WebcamURL", "???");;\
    \
    return "<html><img src=\"$URL\"></html>";;\
}
attr PM webCmd start:stop
Titel: Aw: Weblink mit dynamsicher URL
Beitrag von: Torxgewinde am 28 Oktober 2024, 07:50:21
Um den Devicenamen in der Darstellung auszublenden kann man auch CSS oder wie hier ein JS Schnipsel nutzen und die Zelle vor dem Bild adressieren und unsichtbar machen:

defmod PM HTTPMOD https://www.moselfalken.de/zeltingen-rachtig 600
attr PM reading01Name WebcamURL
attr PM reading01Regex (fileadmin\/_processed_\/\w+\/\w+\/csm_camimg_\d{6}_\d{6}_\w+\.jpg)
attr PM room Experimente
attr PM event-on-change-reading .*
attr PM stateFormat bild
attr PM userReadings bild:WebcamURL:.* {\
    my $URL = "https://www.moselfalken.de/". ReadingsVal($name, "WebcamURL", "???");;\
    \
    # JavaScript snippet with checks to ensure elements exist before applying styles\
    my $JS = "let td=this.closest('td');;";;\
    $JS .= "if(td && td.previousElementSibling) {";;\
    $JS .= "td.previousElementSibling.style.visibility='hidden';;";;\
    $JS .= "td.previousElementSibling.style.padding='0 0 0 0';;";;\
    $JS .= "td.previousElementSibling.style.width='0';;";;\
    $JS .= "}";;\
    \
    return '<html><img src="'.$URL.'" onload="'.$JS.'"></html>';;\
    \
}
attr PM webCmd start:stop

Sieht dann so aus:
Screenshot_2024-10-28_07-50-42.png


Edit #1:
Wenn man will kann man auch Zeit und Datum über dem Bild einblenden, steht ja in der URL mit drin:
defmod PM HTTPMOD https://www.moselfalken.de/zeltingen-rachtig 600
attr PM event-on-change-reading .*
attr PM group Dash
attr PM reading01Name WebcamURL
attr PM reading01Regex (fileadmin\/_processed_\/\w+\/\w+\/csm_camimg_\d{6}_\d{6}_\w+\.jpg)
attr PM room Experimente
attr PM stateFormat bild
attr PM userReadings bild:WebcamURL:.* {\
    my $URL = "https://www.moselfalken.de/". ReadingsVal($name, "WebcamURL", "???");;\
    my $DateTime = "???";;\
    \
    if ($URL =~ /fileadmin\/_processed_\/\w+\/\w+\/csm_camimg_(\d{6})_(\d{6})_\w+\.jpg$/) {\
        my ($date, $time) = ($1, $2);;\
        \
        # Format date (241028 to "2024-10-28") and time (100552 to "10:05:52")\
        my $formatted_date = "20" . substr($date, 0, 2) . "-" . substr($date, 2, 2) . "-" . substr($date, 4, 2);;\
        my $formatted_time = substr($time, 0, 2) . ":" . substr($time, 2, 2) . ":" . substr($time, 4, 2);;\
        \
        $DateTime = $formatted_date.' '.$formatted_time;;\
    }\
    \
    # JavaScript snippet with checks to ensure elements exist before applying styles\
    my $JS = "let td=this.closest('td');;";;\
    $JS .= "if(td && td.previousElementSibling) {";;\
    $JS .= "td.previousElementSibling.style.visibility='hidden';;";;\
    $JS .= "td.previousElementSibling.style.padding='0 0 0 0';;";;\
    $JS .= "td.previousElementSibling.style.width='0';;";;\
    $JS .= "}";;\
    \
    return '<html><img src="'.$URL.'" onload="'.$JS.'"><div style="position: relative;; top: -2em;; left: 1em;; font-size: 2em;;">'.$DateTime.'</div></html>';;\
    \
    }

So sieht es dann aus:
Screenshot_2024-10-28_12-50-13.png
Titel: Aw: Weblink mit dynamsicher URL
Beitrag von: Heiner am 31 Oktober 2024, 09:26:23
Das sieht Klasse aus, vielen Dank.

die Anzeige Groesse des Bildes muestte ich doch eigentlich innerhalb der letzten Zeile dachte ich funktioniert, tuts aber nicht. Wo ist mein Fehler?

vorher:
return '<html><img src="'.$URL.'" onload="'.$JS.'"><div style="position: relative;; top: -2em;; left: 1em;; font-size: 2em;;">'.$DateTime.'</div></html>';;\
nachher:
return '<html><img src="'.$URL.'" onload="'.$JS.'"><div style="position: relative;; top: -2em;; left: 1em;; width: 200px;; font-size: 2em;;">'.$DateTime.'</div></html>';;\
und noch eine Frage: Webseiten inhalte die durch ein script produziert werden und somit nicht direct im sourcecode der Webseite zu finden sind, kann ich den auch irgendwie extrahieren?
z.b.   www.moselfalken.de/ogn zeigt oben "OGN Dashboard  und dann in Klammern einen Script output.  Weiter unten auf der Seite gibts auch noch "Unique pilots" das komplett inklusive dem Wert ein script output ist.

Titel: Aw: Weblink mit dynamsicher URL
Beitrag von: Torxgewinde am 31 Oktober 2024, 15:52:16
Hallo Heiner,
Du bist im falschen HTML Tag, du bist da im <div> mit dem der Zeitstempel umschlossen ist. So kann man es besser sehen und editieren:
defmod PM HTTPMOD https://www.moselfalken.de/zeltingen-rachtig 600
attr PM group Dash
attr PM reading01Name WebcamURL
attr PM reading01Regex (fileadmin\/_processed_\/\w+\/\w+\/csm_camimg_\d{6}_\d{6}_\w+\.jpg)
attr PM room Experimente
attr PM stateFormat bild
attr PM userReadings bild:WebcamURL:.* {\
    my $URL = "https://www.moselfalken.de/". ReadingsVal($name, "WebcamURL", "???");;\
    my $DateTime = "???";;\
    \
    if ($URL =~ m{fileadmin/_processed_/\w+/\w+/csm_camimg_(\d{2})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2})_\w+\.jpg$}) {\
        my ($year, $month, $day, $hour, $minute, $second) = ($1, $2, $3, $4, $5, $6);;\
        \
        my $formatted_date = "20$year-$month-$day";;\
        my $formatted_time = "$hour:$minute:$second";;\
        \
        $DateTime = "$formatted_date $formatted_time";;\
    }\
    \
    # JavaScript snippet with checks to ensure elements exist before applying styles\
    my $JS = "let td=this.closest('td');;";;\
    $JS .= "if(td && td.previousElementSibling) {";;\
    $JS .= "td.previousElementSibling.style.visibility='hidden';;";;\
    $JS .= "td.previousElementSibling.style.padding='0 0 0 0';;";;\
    $JS .= "td.previousElementSibling.style.width='0';;";;\
    $JS .= "}";;\
    \
    ##return '<html><img src="'.$URL.'" onload="'.$JS.'"><div style="position: relative;; top: -2em;; left: 1em;; font-size: 2em;;">'.$DateTime.'</div></html>';;\
    \
    my $html = qq{\
    <html>\
        <img src="$URL" onload="$JS" style="max-width: 200px;; height: auto">\
        <div style="position: relative;; top: -2em;; left: 10px;; font-size: 1em;;">\
            $DateTime\
        </div>\
    </html>\
    };;\
    \
    $html =~ s/\n//g;;\
    return $html;;\
}

Die Live Daten, ja, auch sowas kann man nutzen, allerdings muss man da ohne Doku schon eingiges an Zeit investieren. Also, ja - es geht, ich werde mich da allerdings nicht reinknien. Im Browser kannst du die Entwicklerkonsole nutzen um da an Details zu kommen, vielleicht hilft der Wegweiser bereits...