Hallo zusammen,
das DWD Modul macht Probleme wenn die *_wwd readings aktiviert sind: Text wird in FHEM korrekt dargestellt (auch mit Umlauten), aber wenn über MQTT veröffentlicht ist die Datenkodierung zerschossen und merkwürdige Zeichen werden angezeigt anstelle der deutschen Umlaute. Noch gravierender, Mosquitto beendet die Verbindung wegen einem "malformed packet".
Nach etwa einem Tag Fehlersuche mit Hilfe von ChatGPT konnte ich den Fehler eingrenzen und beheben:
pi@RPi4B-fc3ce3:~$ docker exec fhem sed -n '622,675p' /opt/fhem/FHEM/00_MQTT2_CLIENT.pm
######################################
# send topic to client if its subscriptions matches the topic
sub
MQTT2_CLIENT_doPublish($@)
{
my ($hash, $topic, $val, $retain, $immediate) = @_;
my $name = $hash->{NAME};
return if(IsDisabled($name));
$val = "" if(!defined($val));
if((!$hash->{FD} || $hash->{connecting}) &&
AttrVal($name, "disconnectAfter", undef)) {
$hash->{sendHash} = [] if(!defined($hash->{sendHash}));
push(@{$hash->{sendHash}}, \@_);
MQTT2_CLIENT_connect($hash) if(!$hash->{connecting});
return;
}
MQTT2_CLIENT_updateDisconnectTimer($hash);
if(!$hash->{FD}) {
Log3 $name, 4, "$name: publish to $topic while not connected";
return;
}
my $hdr = 0x30;
my $pi = "";
$hdr += 1 if($retain);
if(defined($hash->{qosQueue}) &&
@{$hash->{qosQueue}} < $hash->{qosMaxQueueLength}) {
$hdr += 2; # QoS:1
push(@{$hash->{qosQueue}}, [$topic,$val,$retain]);
$pi = pack("n",1+($hash->{qosCnt}++%65535)); # Packet Identifier, if QoS > 0
}
#if($unicodeEncoding) {
# $topic = Encode::encode('UTF-8', $topic);
# $val = Encode::encode('UTF-8', $val);
#}
# Proposed fix when setting DWD_OpenData forecastWW2Text=1:
# - no more mosquitto disconnects due to malformed packets
# - DWD *_wwd readings now published with German umlauts (verified with MQTT explorer)
if($unicodeEncoding || utf8::is_utf8($topic) || utf8::is_utf8($val)) {
$topic = Encode::encode('UTF-8', $topic) if utf8::is_utf8($topic);
$val = Encode::encode('UTF-8', $val) if utf8::is_utf8($val);
}
my $msg = pack("C", $hdr).
MQTT2_CLIENT_calcRemainingLength(2+length($topic)+length($val)+
length($pi)).
pack("n", length($topic)).
$topic.$pi.$val;
MQTT2_CLIENT_send($hash, $msg, $immediate);
MQTT2_CLIENT_feedTheList($hash, $topic, $val);
}
Ich habe wenig Ahnung von Perl und vielleicht geht das auch irgendwie eleganter.
Es wäre schön, wenn sich mal jemand der Sache annehmen könnte.
Viele Grüße,
Jan