📬 NTFY.sh: Push Nachrichten an iOS, Android, PC, Command-Line, E-Mail & Telefon

Begonnen von Torxgewinde, 09 Februar 2024, 15:35:12

Vorheriges Thema - Nächstes Thema

Torxgewinde

Ich hatte auch nochmal an meinem Snippet einen weiteren Watchdog zu dem einfachen Wiederverbinden eingefügt, doppelt hält besser... Das sollte damit recht hartnäckig die Verbindung halten und neu aufbauen, außer man gibt den stop-Befehl.

Weiterhin: Erste Wahl ist IMHO der Code von ByteRazor, falls das nicht klappt alternativ den Snippet von mir nehmen.

defmod NTFY_RECEIVE dummy
attr NTFY_RECEIVE userattr URL last_seen_max_age
attr NTFY_RECEIVE URL wss:ntfy.sh:443/FreundlichenGruesseAnAlleFHEMNutzer/ws
attr NTFY_RECEIVE alias NTFY_RECEIVE
attr NTFY_RECEIVE devStateIcon opened:general_ok@green:stop disconnected:rc_STOP@red:start
attr NTFY_RECEIVE eventMap /cmd connect:start/cmd disconnect:stop/
attr NTFY_RECEIVE group Experimente
attr NTFY_RECEIVE icon hue_filled_plug
attr NTFY_RECEIVE last_seen_max_age 600
attr NTFY_RECEIVE readingList cmd
attr NTFY_RECEIVE setList cmd
attr NTFY_RECEIVE userReadings connect:cmd:.connect {\
my $hash = $defs{$name};;\
my $devState = DevIo_IsOpen($hash);;\
return "Device already open" if (defined($devState));;\
\
$hash->{DeviceName} = AttrVal($name, "URL", "wss:ntfy.sh:443/FreundlichenGruesseAnAlleFHEMNutzer/ws");;\
$hash->{header}{'Host'} = 'ntfy.sh';;\
$hash->{header}{'User-Agent'} = 'FHEM';;\
\
$hash->{directReadFn} = sub () {\
my $hash = $defs{$name};;\
readingsBeginUpdate($hash);;\
my $buf = DevIo_SimpleRead($hash);;\
\
# track activity, emtpy buffer normally is from ping/pongs\
readingsBulkUpdate($hash, "last_seen", int(time()*1000));;\
RemoveInternalTimer($name.'Timeout');;\
my $timeoutFunction = sub() {\
my ($arg) = @_;;\
my $hash = $defs{$name};;\
my $myCmd = ReadingsVal($name, "cmd", "disconnect");;\
return if ($myCmd =~ /disconnect|stop/);;\
\
Log3($name, 3, "$name: Timeout occured, restarting websocket...");;\
DevIo_CloseDev($hash);;\
readingsBeginUpdate($hash);;\
readingsBulkUpdate($hash, "state", "disconnected");;\
readingsBulkUpdate($hash, "cmd", "connect", 1);;\
readingsEndUpdate($hash, 1);;\
};;\
InternalTimer(gettimeofday() + 120, $timeoutFunction, $name.'Timeout');;\
\
if(!defined($buf)) {\
DevIo_CloseDev($hash);;\
#readingsBulkUpdate($hash, "last_seen", 0);;\
$buf = "not_connected";;\
}\
\
# only update our reading if buffer is not empty and looks like it contains a message\
if ($buf ne "" && \
    $buf =~ /^{.*"event":"message".*}$/) { ## check if buffer looks like JSON with msg\
\
# delete all our readings that begin with "ntfy_"\
foreach my $reading (grep { $_ =~ /^ntfy_.*/ } keys %{$hash->{READINGS}}) {\
readingsDelete($hash, $reading);;\
}\
\
# parse as JSON, do not trust the input fully, thus sanitize buffer\
my %res = %{json2nameValue($buf)};; #(https://wiki.fhem.de/wiki/MQTT2_DEVICE_-_Schritt_f%C3%BCr_Schritt#json2nameValue.28.29)\
foreach my $k (sort keys %res) {\
# only keep ASCII and a German Characters like Umlaute, sharp-S...\
my $sanitizedValue = $res{$k} =~ s/[^[:ascii:]äöüÖÄÜß]/_/rg;; # 'r' flag prevents modifying the input string\
readingsBulkUpdate($hash, "ntfy_".makeReadingName($k), $sanitizedValue);;\
}\
}\
#readingsBulkUpdate($hash, "websocketData", "$buf") if ($buf ne "");;\
Log3($name, 3, "$name: Rx: >>>$buf<<<") if ($buf ne "");;\
\
readingsEndUpdate($hash, 1);;\
};;\
\
DevIo_OpenDev($hash,\
0,      ## reopen flag\
undef,  ## initFn, on success\
sub() { ## callbackFn, on verdict, req. to make it a non-blocking call\
my ($hash, $error) = @_;;\
if ($error) {\
Log(3, "$name: DevIo_OpenDev Callback: connection failed: $error");;\
\
my $timerFunction = sub() {\
my ($arg) = @_;;\
my $hash = $defs{$name};;\
my $devState = DevIo_IsOpen($hash);;\
readingsSingleUpdate($hash, "cmd", "connect", 1) if (!defined($devState));;\
};;\
\
RemoveInternalTimer($name.'Timer');;\
my $rwait = int(rand(20)) + 10;;\
InternalTimer(gettimeofday() + $rwait, $timerFunction, $name.'Timer');;\
readingsSingleUpdate($hash, "cmd", "reconnect attempt in $rwait seconds", 1);;\
}\
}\
);;\
\
readingsBulkUpdate($hash, "state", "connecting...");;\
return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
disconnect:cmd:.(disconnect|reconnect) {\
my $hash = $defs{$name};;\
my $myCmd = ReadingsVal($name, "cmd", "???");;\
\
RemoveInternalTimer($name.'Timer');;\
RemoveInternalTimer($name.'Timeout');;\
DevIo_CloseDev($hash);;\
readingsBulkUpdate($hash, "state", "disconnected") if (!defined(DevIo_IsOpen($hash)));;\
\
if ($myCmd =~ /reconnect/) {\
my $timerFunction = sub() {\
my $hash = $defs{$name};;\
readingsSingleUpdate($hash, "cmd", "connect", 1);;\
};;\
\
RemoveInternalTimer("${name}_${reading}_timer");;\
InternalTimer(gettimeofday()+1, $timerFunction, "${name}_${reading}_timer");;\
} else {\
RemoveInternalTimer("${name}_watchdog_timer");;\
}\
\
return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
onDisconnect { ## check on each update if the connection is unintentionally broken...\
my $myState = ReadingsVal($name, "state", "???");;\
my $myData = ReadingsVal($name, "websocketData", "???");;\
my $myCmd = ReadingsVal($name, "cmd", "disconnect");;\
return if ($myState ne "disconnected" and $myData ne "not_connected");;\
return if ($myCmd =~ /disconnect|stop/);;\
\
my $timerFunction = sub() {\
my ($arg) = @_;;\
my $hash = $defs{$name};;\
my $devState = DevIo_IsOpen($hash);;\
readingsSingleUpdate($hash, "cmd", "connect", 1) if (!defined($devState));;\
};;\
\
RemoveInternalTimer($name.'Timer');;\
my $rwait = int(rand(20)) + 10;;\
InternalTimer(gettimeofday() + $rwait, $timerFunction, $name.'Timer');;\
readingsBulkUpdate($hash, "cmd", "reconnect attempt in $rwait seconds");;\
\
return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
watchdog:last_seen:.* {\
my $ls = ReadingsVal($name, "last_seen", 0);;\
\
my $timerFunction = sub() {\
##fhem("set FHEMMeldung.ntfy message $name $reading wurde ausgelöst (last_seen: $ls)");;\
readingsSingleUpdate($hash, "cmd", "reconnect", 1);;\
readingsSingleUpdate($hash, "last_seen", 0, 1);;\
};;\
\
RemoveInternalTimer("${name}_${reading}_timer");;\
InternalTimer(gettimeofday()+240, $timerFunction, "${name}_${reading}_timer");;\
\
return POSIX::strftime("%H:%M:%S", localtime(time()));;\
}
attr NTFY_RECEIVE verbose 1
attr NTFY_RECEIVE webCmd start:stop

Torxgewinde

Kleines Update, falls mit meinem Snippet auch Nutzername und Passwort (als Attribute "username" und "password") genutzt werden sollen:

defmod NTFY_RECEIVE dummy
attr NTFY_RECEIVE userattr URL last_seen_max_age password username
attr NTFY_RECEIVE URL wss:ntfy.sh:443/FreundlichenGruesseAnAlleFHEMNutzer/ws
attr NTFY_RECEIVE alias NTFY_RECEIVE
attr NTFY_RECEIVE devStateIcon opened:general_ok@green:stop disconnected:rc_STOP@red:start
attr NTFY_RECEIVE eventMap /cmd connect:start/cmd disconnect:stop/
attr NTFY_RECEIVE group Experimente
attr NTFY_RECEIVE icon hue_filled_plug

attr NTFY_RECEIVE password superGeheimesPasswort
attr NTFY_RECEIVE readingList cmd

attr NTFY_RECEIVE setList cmd
attr NTFY_RECEIVE userReadings connect:cmd:.connect {\
    my $hash = $defs{$name};;\
    my $devState = DevIo_IsOpen($hash);;\
    return "Device already open" if (defined($devState));;\
    \
    $hash->{DeviceName} = AttrVal($name, "URL", "wss:ntfy.sh:443/FreundlichenGruesseAnAlleFHEMNutzer/ws");;\
    $hash->{DeviceName} =~ m,^(ws:|wss:)?([^/:]+):([0-9]+)(.*?)$,;;\
    $hash->{header}{'Host'} = $2;;\
    $hash->{header}{'User-Agent'} = 'FHEM';;\
    \
    my $user = AttrVal($name, "username", "???");;\
    my $pwd  = AttrVal($name, "password", "???");;\
    if ($user ne "???" && $pwd ne "???") {\
        my $encoded_auth = MIME::Base64::encode_base64("$user:$pwd", "");;\
        $hash->{header}{'Authorization'} = "Basic $encoded_auth";;\
    }\
    \
    $hash->{directReadFn} = sub () {\
        my $hash = $defs{$name};;\
        readingsBeginUpdate($hash);;\
        my $buf = DevIo_SimpleRead($hash);;\
        \
        # track activity, emtpy buffer normally is from ping/pongs\
        readingsBulkUpdate($hash, "last_seen", int(time()*1000));;\
        RemoveInternalTimer($name.'Timeout');;\
        my $timeoutFunction = sub() {\
            my ($arg) = @_;;\
            my $hash = $defs{$name};;\
            my $myCmd = ReadingsVal($name, "cmd", "disconnect");;\
            return if ($myCmd =~ /disconnect|stop/);;\
            \
            Log3($name, 3, "$name: Timeout occured, restarting websocket...");;\
            DevIo_CloseDev($hash);;\
            readingsBeginUpdate($hash);;\
            readingsBulkUpdate($hash, "state", "disconnected");;\
            readingsBulkUpdate($hash, "cmd", "connect", 1);;\
            readingsEndUpdate($hash, 1);;\
        };;\
        InternalTimer(gettimeofday() + 120, $timeoutFunction, $name.'Timeout');;\
        \
        if(!defined($buf)) {\
            DevIo_CloseDev($hash);;\
            #readingsBulkUpdate($hash, "last_seen", 0);;\
            $buf = "not_connected";;\
        }\
        \
        # only update our reading if buffer is not empty and looks like it contains a message\
        if ($buf ne "" && \
            $buf =~ /^{.*"event":"message".*}$/) { ## check if buffer looks like JSON with msg\
            \
            # delete all our readings that begin with "ntfy_"\
            foreach my $reading (grep { $_ =~ /^ntfy_.*/ } keys %{$hash->{READINGS}}) {\
                readingsDelete($hash, $reading);;\
            }\
            \
            # parse as JSON, do not trust the input fully, thus sanitize buffer\
            my %res = %{json2nameValue($buf)};; #(https://wiki.fhem.de/wiki/MQTT2_DEVICE_-_Schritt_f%C3%BCr_Schritt#json2nameValue.28.29)\
            foreach my $k (sort keys %res) {\
                # only keep ASCII and a German Characters like Umlaute, sharp-S...\
                my $sanitizedValue = $res{$k} =~ s/[^[:ascii:]äöüÖÄÜß]/_/rg;; # 'r' flag prevents modifying the input string\
                readingsBulkUpdate($hash, "ntfy_".makeReadingName($k), $sanitizedValue);;\
            }\
        }\
        #readingsBulkUpdate($hash, "websocketData", "$buf") if ($buf ne "");;\
        Log3($name, 3, "$name: Rx: >>>$buf<<<") if ($buf ne "");;\
        \
        readingsEndUpdate($hash, 1);;\
    };;\
    \
    DevIo_OpenDev($hash,\
        0,      ## reopen flag\
        undef,  ## initFn, on success\
        sub() { ## callbackFn, on verdict, req. to make it a non-blocking call\
            my ($hash, $error) = @_;;\
            if ($error) {\
                Log(3, "$name: DevIo_OpenDev Callback: connection failed: $error");;\
                \
                my $timerFunction = sub() {\
                    my ($arg) = @_;;\
                    my $hash = $defs{$name};;\
                    my $devState = DevIo_IsOpen($hash);;\
                    readingsSingleUpdate($hash, "cmd", "connect", 1) if (!defined($devState));;\
                };;\
                \
                RemoveInternalTimer($name.'Timer');;\
                my $rwait = int(rand(20)) + 10;;\
                InternalTimer(gettimeofday() + $rwait, $timerFunction, $name.'Timer');;\
                readingsSingleUpdate($hash, "cmd", "reconnect attempt in $rwait seconds", 1);;\
            }\
        }\
    );;\
    \
    readingsBulkUpdate($hash, "state", "connecting...");;\
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
disconnect:cmd:.(disconnect|reconnect) {\
    my $hash = $defs{$name};;\
    my $myCmd = ReadingsVal($name, "cmd", "???");;\
    \
    RemoveInternalTimer($name.'Timer');;\
    RemoveInternalTimer($name.'Timeout');;\
    DevIo_CloseDev($hash);;\
    readingsBulkUpdate($hash, "state", "disconnected") if (!defined(DevIo_IsOpen($hash)));;\
    \
    if ($myCmd =~ /reconnect/) {\
        my $timerFunction = sub() {\
            my $hash = $defs{$name};;\
            readingsSingleUpdate($hash, "cmd", "connect", 1);;\
        };;\
    \
        RemoveInternalTimer("${name}_${reading}_timer");;\
        InternalTimer(gettimeofday()+1, $timerFunction, "${name}_${reading}_timer");;\
    } else {\
        RemoveInternalTimer("${name}_watchdog_timer");;\
    }\
    \
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
onDisconnect { ## check on each update if the connection is unintentionally broken...\
    my $myState = ReadingsVal($name, "state", "???");;\
    my $myData = ReadingsVal($name, "websocketData", "???");;\
    my $myCmd = ReadingsVal($name, "cmd", "disconnect");;\
    return if ($myState ne "disconnected" and $myData ne "not_connected");;\
    return if ($myCmd =~ /disconnect|stop/);;\
    \
    my $timerFunction = sub() {\
        my ($arg) = @_;;\
        my $hash = $defs{$name};;\
        my $devState = DevIo_IsOpen($hash);;\
        readingsSingleUpdate($hash, "cmd", "connect", 1) if (!defined($devState));;\
    };;\
    \
    RemoveInternalTimer($name.'Timer');;\
    my $rwait = int(rand(20)) + 10;;\
    InternalTimer(gettimeofday() + $rwait, $timerFunction, $name.'Timer');;\
    readingsBulkUpdate($hash, "cmd", "reconnect attempt in $rwait seconds");;\
    \
    return POSIX::strftime("%H:%M:%S",localtime(time()));;\
},\
watchdog:last_seen:.* {\
    my $ls = ReadingsVal($name, "last_seen", 0);;\
        \
    my $timerFunction = sub() {\
        ##fhem("set FHEMMeldung.ntfy message $name $reading wurde ausgelöst (last_seen: $ls)");;\
        readingsSingleUpdate($hash, "cmd", "reconnect", 1);;\
        readingsSingleUpdate($hash, "last_seen", 0, 1);;\
    };;\
    \
    RemoveInternalTimer("${name}_${reading}_timer");;\
    InternalTimer(gettimeofday()+240, $timerFunction, "${name}_${reading}_timer");;\
    \
    return POSIX::strftime("%H:%M:%S", localtime(time()));;\
}
attr NTFY_RECEIVE username Torxgewinde
attr NTFY_RECEIVE verbose 1
attr NTFY_RECEIVE webCmd start:stop

isy

Moin zusammen,
kann man mit dem Snippet (oder dem Modul?) auch Bilder versenden?
Ähnlich wie mit dem Telegram Modul?

VG Helmut
Ein Weg wird erst zu einem Weg, wenn man ihn geht

Torxgewinde

Stand bis jetzt erstmal nicht (Weder in meinem Snippet, noch in ByteRazors: https://rm.byterazor.de/issues/27)

Es gibt zwei Methoden die NTFY für Bilder annehmen kann:

In welchem Format läge dein Bild denn vor?
  • Hast du Bilddaten und keine öffentlich erreichbare URL für die Empfänger, dann wäre die HTTP-PUT Methode sinnvoller.
  • Wäre es von einer externen URL aus erreichbar? Dann wäre die Methode mit der URL in dem Header sinnvoll.

isy

Es handelt sich um jpg Files vom PI eigenen Directory /opt/fhem usw. Also per put wäre die Option.

Ich habe mir aber gedacht, dass die Funktion zumindest aktuell nicht geht und sende das Bild per debianmail. Dauert halt bei iOS Endgeräten immer recht lange, da Push-Mail nicht funktioniert.
Ein Weg wird erst zu einem Weg, wenn man ihn geht

Torxgewinde

Ok, ich behalt es mal im Kopf. Sollte sich eigentlich auch mit FHEM machen lassen, spricht ja nix dagegen, außer dass ich Zeit finde.

Ich hatte was ähnliches mit NTFY gemacht um mir die Bilder meiner Carport-Kamera in NTFY zu senden. Da sendet die Kamera die E-Mails und die poppen in NTFY dann ziemlich direkt auf: https://forum.fhem.de/index.php?topic=139868.msg1325988
Da du per Mail versendest ist das vielleicht bereits jetzt OK genug, auch wenn es ein weniger hin- und hergeht mit den Daten.

isy

Spannend deine Lösung im verlinkten Thread.
Für mich wäre das etwas zu aufwändig.

Gerade noch gefunden:
https://ntfy.geraffel.org/docs/publish/#__tabbed_24_1
Ein Weg wird erst zu einem Weg, wenn man ihn geht

Torxgewinde

Probier es mal aus:

defmod NTFY HTTPMOD none 0
attr NTFY userattr Filename Markdown NtfyServer Priority Title Topic password username
attr NTFY Filename test.png
attr NTFY Markdown true
attr NTFY NtfyServer ntfy.sh
attr NTFY Priority high
attr NTFY Title Titel aus UserAttr heraus
attr NTFY Topic FreundlichenGruesseAnAlleFHEMNutzer
attr NTFY comment # for HTTP Basic authentication use this as "setUrl":\
# https://[$name:username]:[$name:password]@[$name:NtfyServer]/%%path%%
attr NTFY replacement01Mode text
attr NTFY replacement01Regex %%path%%
attr NTFY replacement02Mode expression
attr NTFY replacement02Regex \[([^:]+):([^\]]+)\]
attr NTFY replacement02Value my $device = $name if ($1 eq "\$name") // $1;;\
ReadingsVal($device, $2, undef) or AttrVal($device, $2, "???");;
attr NTFY replacement03Mode expression
attr NTFY replacement03Regex %%title%%
attr NTFY replacement04Mode expression
attr NTFY replacement04Regex %%message%%
attr NTFY replacement05Mode expression
attr NTFY replacement05Regex %%file%%
attr NTFY room Global
attr NTFY set1Data %%message%%
attr NTFY set1HeaderIcon Icon: https://fhem.de/www/images/default/fhemicon.png
attr NTFY set1HeaderMarkdown Markdown: [$name:Markdown]
attr NTFY set1HeaderPrio Priority: [$name:Priority]
attr NTFY set1HeaderTitle Title: %%title%%
attr NTFY set1Method POST
attr NTFY set1Name message
attr NTFY set1Replacement01Value [$name:Topic]
attr NTFY set1Replacement03Value # get the value as passed to the set command:\
my $value = InternalVal($name, "value", "???");;\
\
# find first occurence of pattern Title=".*" and use that as result:\
my ($result) = $value =~ /Title="(.*?)"/;;\
\
# assign value from userAttr if $result is emtpy:\
$result //= AttrVal($name, "Title", "???");;\
\
return $result;;
attr NTFY set1Replacement04Value # get the value as passed to the set command:\
my $value = InternalVal($name, "value", "???");;\
\
# remove everything matching pattern Title=".*"\
$value =~ s/Title=".*?"//;;\
\
#replace the literal character sequence\
# \n with a real linefeed\
$value =~ s/\\n/\n/g;;\
\
return $value;;
attr NTFY set1TextArg 1
attr NTFY set2Data %%file%%
attr NTFY set2HeaderFilename Filename: [$name:Filename]
attr NTFY set2HeaderPrio Priority: [$name:Priority]
attr NTFY set2HeaderTitle Title: [$name:Title]
attr NTFY set2Method PUT
attr NTFY set2Name attach
attr NTFY set2Replacement01Value [$name:Topic]
attr NTFY set2Replacement05Value my $value = InternalVal($name, "value", "???");;\
\
open(my $fh, '<', $value) or return "ERROR: Cannot open file";;\
binmode($fh);; \
my $result = do { local $/;; <$fh> };; \
close($fh);; \
\
return $result;;
attr NTFY set2TextArg 1
attr NTFY setURL https://[$name:NtfyServer]/%%path%%
attr NTFY widgetOverride Priority:select,max,high,default,low,min Markdown:select,true,false

Senden einer Datei geht wie in diesem Beispiel:
set NTFY attach /opt/fhem/www/images/default/fhemicon.png

Wie die Datei beim Empfänger heißen soll, bestimmt der Parameter "Filename". Dies kann man als Reading oder Attribut setzen, das Reading hat Vorrang:
  • setreading NTFY Filename meinDateiName.jpg
  • attr NTFY Filename meinDateiName.jpg

Eine Demo ist kurzzeitig auf: https://demo-fhem.cooltux.net/fhem?detail=NTFY

So sieht es dann aus:
Du darfst diesen Dateianhang nicht ansehen.

Edit #1: Habe die Formatierung verbessert und ein weniger deutlicher beschrieben wie man den Dateinamen setzt.

isy

Hallo Torxgewinde,
das funktioniert. Toll!
Getestet habe ich mit einem jpg Bild und einem mp4 Video.


Vielen, vielen Dank!
Sehr schön, auch den Dateinamen, den ich als Ursprung verstehe, per attr variabel setzen zu können.

Ich hatte mir vor ein paar Tagen Blink Kameras zugelegt und habe bislang Videos und Bilder per Mail versandt.
Das kann ich nun zumindest für die Bilder umbauen, denn bei den Videos habe ich wegen der Dateigröße etwas Bedenken wegen der Nutzung des Gratis-Servers. Wenn die Bilder schnell ankommen, können die Videos ja warten oder wir rufen die Mail selbst ab. Das klappt dann schon mit dem nötigen WAF.

Beste Grüße,
Helmut
Ein Weg wird erst zu einem Weg, wenn man ihn geht

isy

Ich habe noch ein paar Zeilen im Log gefunden, evtl. fehlt mir noch eine Eingabe?

2025.02.14 13:45:40 3: NTFY: URL is none, periodic updates will be limited to explicit GetXXPoll attribues (if defined)
2025.02.14 13:45:40 3: NTFY: interval is 0, no periodic updates will done.
2025.02.14 13:45:40 3: NTFY: Defined without URL featurelevel 6.3
Ein Weg wird erst zu einem Weg, wenn man ihn geht

isy

Die Meldungen kamen 2* und aktuell nicht mehr.
Getestet mit Text, Bild und Video Anhang.
Ein Weg wird erst zu einem Weg, wenn man ihn geht

Torxgewinde

Zitat von: isy am 14 Februar 2025, 14:13:06Ich habe noch ein paar Zeilen im Log gefunden, evtl. fehlt mir noch eine Eingabe?

2025.02.14 13:45:40 3: NTFY: URL is none, periodic updates will be limited to explicit GetXXPoll attribues (if defined)
2025.02.14 13:45:40 3: NTFY: interval is 0, no periodic updates will done.
2025.02.14 13:45:40 3: NTFY: Defined without URL featurelevel 6.3

Das ist OK und kann ignoriert werden. HTTPMOD kann ja auch Webseiten abrufen und auswerten, das macht der Snippet aber nicht. Es gibt keine URL zum Abrufen --> "URL is none" und es soll auch nicht zyklisch probiert werden "interval is 0".

Torxgewinde


isy

Ein Weg wird erst zu einem Weg, wenn man ihn geht

isy

Ich habe soeben bemerkt, dass die iOS App (auf einem iPhone mit 18.3.1) und die iPadOS App (auf einem M2 MAC mit MacOS 15.3.1) beide kein Bild anzeigen.
Soll ich mal den Entwickler anschreiben?
Ein Weg wird erst zu einem Weg, wenn man ihn geht