UTF-8 Probleme bei NTFY

Begonnen von matkoh, 14 April 2026, 15:38:11

Vorheriges Thema - Nächstes Thema

matkoh

Hallo,

ich habe lange Nachrichten aus FHEM per SignalBot gesandt. Vor kurzem wurden keine Nachrichten mehr versandt und in Signal auf dem Smartphone erschien "Diese Person verwendet Signal nicht mehr". Ich habe ein Update von signal-cli vorgenommen, bekam die Authentifizierung in FHEM aber nicht mehr hin.

Nun bin ich auf NTFY umgestiegen, wie in https://wiki.fhem.de/wiki/Ntfy beschrieben. Grundsätzlich funktioniert alles, aber eine Nachricht wird nicht versendet. Da erscheint im fhem.log die Meldung
Encoding problem in data/header (not UTF-8), check Forum #131207
Ich habe die Zeitzone und lokale Sprache auf dem Raspi nochmals eingestellt und neu gestartet. Das ändert aber nichts.

Hier ist der Code aus einem DOIF, der verwendet wird:
## 1
 ([6:00|8] or [8:00|7])
  ({fhem("set NTFY0 publish \@FHEM-Status Tägliche Statusmeldung
  \nGarage hinten:
  \nTemperatur: ".ReadingsVal("Aussen.Temp","temperature","").
  "\nLuftfeuchtigkeit: ".ReadingsVal("Aussen.Temp","humidity","")." %
  \nHeizung: ".ReadingsVal("Buderus","OutdoorTemp","")."
  \nVorne: ".ReadingsVal("MQTT2_Aussen.Temperatur.vorne","temperature","")."
  \nWettervorhersage heute: ".ReadingsVal("DWD","fc0_3_wwd","")."
  \nTag/Nacht: ".ReadingsVal("DWD","fc0_Tx","")." / ".ReadingsVal("DWD","fc0_Tn","")."
  \nWettervorhersage morgen: ".ReadingsVal("DWD","fc1_2_wwd","")."
  \nTag/Nacht: ".ReadingsVal("DWD","fc1_Tx","")." / ".ReadingsVal("DWD","fc1_Tn","")."
  \nBatterie PV: ".ReadingsVal("SolarEdgeAPI","status-storage_level","")." %"
  )
  })
und hier das Ergebnis, wie es im Reading von NTFY0 erscheint:
Taegliche Statusmeldung
Garage hinten:
Temperatur: 16.4
Luftfeuchtigkeit: 50 %
Heizung: 14.4
Vorne: 17.1
Wettervorhersage heute: Bewölkung abnehmend
Tag/Nacht: 16.8 / 4.80
Wettervorhersage morgen: Bewölkung abnehmend
Tag/Nacht: 20.4 / 7.5
Batterie PV: 65 %

Ich vermute, dass die Readings aus DWD die Probleme verursachen wegen des Umlauts in "Bewölkung". Mit SignalBot wurde diese Nachricht übertragen. Andere Nachrichten im selben DOIF ohne Umlaute werden auch übertragen.

Hat jemand eine Idee, wie ich das Problem lösen kann?

Matthias



rudolfkoenig

Ist "attr global encoding" gesetzt?

Soweit ich sehe, ist 55_DWD_OpenData.pm unproblematisch, da es das Attribut (bzw. $unicodeEncoding) prueft.
Ich habe sowas in 98_NTFY_CLIENT.pm nicht gesehen, d.h. es duerfte nur mit der Voreinstellung (attr global encoding bytestream) klarkommen.

matkoh

Das "attr global encoding" war nicht gesetzt, es müsste also bytestream aktiv sein.

Ich habe zuerst
attr global encoding bytestreamgesetzt, das führt zu folgenden Fehlern im Log, wenn die Statusmeldung versandt wird:
2026.04.15 14:13:16 1: Encoding problem in data/header (not UTF-8), check Forum #131207
2026.04.15 14:13:16 1: PERL WARNING: substr outside of string at FHEM/HttpUtils.pm line 811.
2026.04.15 14:13:16 1: PERL WARNING: Use of uninitialized value $data in numeric eq (==) at FHEM/HttpUtils.pm line 812.

Dann habe ich
attr global encoding unicodegesetzt. Wird dann die Statusmeldung versandt, gibt es keine Fehler mehr im Log, aber die Meldung kommt mit falschen Umlauten:
Taegliche Statusmeldung
Garage hinten:
Temperatur: 21.3
Luftfeuchtigkeit: 36 %
Heizung: 17.1
Vorne: 23.1
Wettervorhersage heute: Bewölkung unverändert
Tag/Nacht: 20.4 / 6.80
Wettervorhersage morgen: Bewölkung unverändert
Tag/Nacht: 19 / 10.6
Batterie PV: 94 %

Matthias

matkoh

#3
Jetzt werde ich
attr global encoding unicodenicht mehr los. Immer, wenn ich auf bytestream ändere (egal, ob im Gerät global oder mit attr) startet fhem neu und das Attribut encoding ist immer noch auf unicode.

Und das betrifft leider jede Änderung. Auch wenn ich ein Gerät lösche und die Konfiguration speichere (ich arbeite mit configDB), wird ein Neustart von fhem ausgelöst und die Änderung ist rückgängig gemacht.

Ich wäre dankbar für einen Tipp, wie ich das encoding-Attribut entweder loswerde (löschen geht auch nicht) oder auf bytestream setzen kann. Bis dahin kann ich nur eingeschränkt mit fhem arbeiten.

matkoh

Ich konnte mit
configdb recover 1die letzte Version mit
attr global encode bytestreamwiederherstellen. Jetzt kann ich wieder normal arbeiten - das Senden der Statusmeldung funktioniert aber nicht.

matkoh

Ich habe einen Workaround gefunden, der nicht schön ist, aber funktioniert. In der 99_myUtils.pm habe ich eine neue Funktion eingetragen:
sub UmlauteErsetzen($) {
my ($Val) = @_;
$Val =~ s/Bewölkung/Bewoelkung/;
$Val =~ s/unverändert/unveraendert/;
return $Val
}
und dann den Code im DOIF geändert:
## 1
 ([6:00|8] or [8:00|7])
  ({fhem("set NTFY0 publish \@FHEM-Status Taegliche Statusmeldung
  \nGarage hinten:
  \nTemperatur: ".ReadingsVal("Aussen.Temp","temperature","").
  "\nLuftfeuchtigkeit: ".ReadingsVal("Aussen.Temp","humidity","")." %
  \nHeizung: ".ReadingsVal("Buderus","OutdoorTemp","")."
  \nVorne: ".ReadingsVal("MQTT2_Aussen.Temperatur.vorne","temperature","")."
  \nWettervorhersage heute: ".UmlauteErsetzen(ReadingsVal("DWD","fc0_3_wwd",""))."
  \nTag/Nacht: ".ReadingsVal("DWD","fc0_Tx","")." / ".ReadingsVal("DWD","fc0_Tn","")."
  \nWettervorhersage morgen: ".UmlauteErsetzen(ReadingsVal("DWD","fc1_2_wwd",""))."
  \nTag/Nacht: ".ReadingsVal("DWD","fc1_Tx","")." / ".ReadingsVal("DWD","fc1_Tn","")."
  \nBatterie PV: ".ReadingsVal("SolarEdgeAPI","status-storage_level","")." %"
  )
  })

Mir ist klar, dass auch andere Texte mit Umlauten aus DWD kommen können. Kennt jemand eine Übersicht der möglichen Forecast-Meldungen (xx_wwd)? Oder, noch besser, hat jemand einen Tipp, wie ich über fehlgeschlagene Sendungen mit NTFY informiert werden kann? Bisher sehe ich nur eine Meldung im fhem.log, schön wäre eine Fehlermeldung, die auch mit NTFY versandt wird.

rudolfkoenig

ZitatIn der 99_myUtils.pm habe ich eine neue Funktion eingetragen:
Eine generische Variante ist in fhem.pl => makeReadingName() implementiert, leider ist es nicht ganz ideal in diesem Fall, da Leerzeichen durch _ ersetzt werden.

ZitatKennt jemand eine Übersicht der möglichen Forecast-Meldungen (xx_wwd)?
Die komplette Liste ist FHEM/55_DWD_OPenData.pm zu sehen (https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/55_DWD_OpenData.pm#L660), da XX_wwd in diesem Modul aus XX_ww berechnet wird.

ZitatOder, noch besser, hat jemand einen Tipp, wie ich über fehlgeschlagene Sendungen mit NTFY informiert werden kann?
Ein notify mit dem readLog Attribut liest das FHEM-Log, und kann mit passenden Regexp reagieren.

passibe

Nur zur Info, das von dir verwendete Modul wird nicht mehr weiterentwickelt bzw. ist (jedenfalls für mich) auch gar nicht mehr von den im Wiki angegebenen Quellen herunterladbar. Weiß aber nicht, ob dein Fehler damit zusammenhängt ...

Jedenfalls, vielleicht hilft dir ja meine Minimalimplementierung hier:
https://forum.fhem.de/index.php?topic=137036.msg1356258#msg1356258
Das ganze $cmd1, $button1,-Zeugs kannst du weglassen. Bei mir jedenfalls hat das out of the box auch mit Umlauten funktioniert.

Ich nutze das aber nur zum Senden von Benachrichtigungen, FHEM "liest" keine ntfy-Nachrichten (Rückmeldung bzw. Befehle laufen nur über diese Buttons).

matkoh

@passibe danke, das ist eine gute Anregung. Allerdings benötige ich keine Actions, dafür möchte ich aber das Topic bei jeder Nachricht festlegen können (wie es im nicht mehr weiterentwickelten Modul implementiert ist). Dein Code passt also nicht so ganz. Vielleicht kann ich mir aber eine passende Funktion selber basteln. Oder ich versuche es mit dem HTTPMOD Beispiel aus https://wiki.fhem.de/wiki/Ntfy, obwohl auch da scheinbar ein festes Topic verwendet wird.

passibe

Ich denke, so könnte es klappen? Ist aber ungetestet.

Habe nur eine neue Variable $topic gemacht, die stumpf an die URL drangehängt wird. Das ganze Button-Zeug ist raus. Message steht nach wie vor vorne, damit man auch ohne Angabe eines topic eine Nachricht an ein default topic schicken kann.

sub ntfy {
    my ($message, $topic, $priority, $tags, $title) = @_;
   
    # Set defaults
        if (!defined $topic) {$topic = "fhem"}
        if (!defined $priority) {$priority = 3}
        if (!defined $tags) {$tags = "house_with_garden"};
        if (!defined $title or $title eq "") {$title = "FHEM"}
        if ($tags !~ m/house_with_garden/) {
            $tags = $tags.",house_with_garden";
        }

    # Prepare headers
        my $param = {
            url => "https://ntfy.example.org/$topic",
            method => "POST",
            timeout => 10,
            callback => sub() {},
            header => "Content-Type: application/json\r\nAuthorization: Bearer REDACTED\r\np: $priority\r\nta: $tags\r\nt: $title",
            data => $message
        };

    # Make request
    HttpUtils_NonblockingGet($param);
}