Hauptmenü

Neueste Beiträge

#1
FRITZ!Box / Aw: 72_FRITZBOX.pm wird zu 72_...
Letzter Beitrag von pfeffi - 21 September 2026, 13:30:37
Okay, jetzt verstehe ich das

https://www.swisstransfer.com/dl/01a0c3b5-f579-70da-a723-cb821c779e93

<!DOCTYPE html>
<html lang="de">
<head>
  <meta http-equiv=content-type content="text/html; charset=utf-8" />
<meta http-equiv="Cache-Control" content="private, no-transform" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="format-detection" content="telephone=no" />
<meta http-equiv="x-rim-auto-match" content="none" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes, minimal-ui" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta http-equiv="cleartype" content="on">
<link rel="icon" href="/favicon.ico" size="16x16"/>
<link rel="icon" href="/icon.svg" type="image/svg+xml"/>
<link rel="icon" href="/icon.png" type="image/png"/>
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="apple-touch-startup-image" href="/apple-touch-icon.png" />
<style>
  @font-face {
    font-family: 'Source Sans Pro';
    font-style: normal;
    font-stretch: normal;
    font-weight: 400;
    src: url('/assets/fonts/SourceSansPro-Regular.woff2') format('woff2');
  }
  @font-face {
    font-family: 'Source Sans Pro';
    font-style: normal;
    font-stretch: normal;
    font-weight: 600;
    src: url('/assets/fonts/SourceSansPro-SemiBold.woff2') format('woff2');
  }
  @font-face {
    font-family: 'Source Sans Pro';
    font-style: normal;
    font-stretch: normal;
    font-weight: 900;
    src: url('/assets/fonts/SourceSansPro-Black.woff2') format('woff2');
  }
  html, input, textarea, keygen, select, button {
    font-family: 'Source Sans Pro', Arial, sans-serif;
    font-size: 100%;
  }
</style>

  <link rel="stylesheet" type="text/css" href="/css/box.css">
  <link rel='stylesheet' type='text/css' href="/css/rd/login.css"/>
  <title>
          FRITZ!Repeater
  </title>
</head>
<body>
  <script>
    var gNbc = false;
  </script>
  <script src="/js/browser.js"></script>
  <script src="/js/vendor.js"></script>
  <script src="/js/box-login.js"></script>
  <script type="module">
    import { setConfig } from "/js/config.js";
    import login from "/js/login.js";
    setConfig({"ZIGBEE":false,"PRODUKT_NAME":"FRITZ!Repeater 3000","GUI_IS_POWERLINE":false,"isDebug":false,"WLAN":{"has_5ghz_band":false,"has_wpa2_wpa3_mixed_support":false,"has_wpa2_support":true,"omit_macfilter":false,"is_triband":false,"has_wpa_tkip_support":false,"is_double_wlan":false,"has_wpa3_support":false,"has_6ghz_band":false,"has_wpa_wpa2_mixed_support":false},"oem":"avm","gu_type":"release","GUI_IS_MESH_SET":false,"GUI_HIDE_TEASER":false,"isPartOfMeshSet":false,"GUI_IS_REPEATER":true,"GUI_IS_GATEWAY":false,"language":"de","GUI_IS_INHAUS_OR_LABBETA":false});
    const data = {"firstTenMin":false,"challenge":"2$60000$5c8062585003a2403789b94fa53ed5af$6000$2eda75dcffec0c9925e0de1c81ff6a2d","blockTime":0,"pageTitle":"Willkommen bei Ihrem FRITZ!Repeater 3000","lastPage":"","hideForgotPasswordLink":true,"loginReason":0,"username":"Udo55","abortConfig":false,"authMode":"2","fallbackRedirectUrl":"http:\/\/192.168.178.2\/","facTitle":"FRITZ!Repeater-Werkseinstellungen","falseUsername":false,"pageTitleProduct":"FRITZ!Repeater 3000","showFactoryPasswordHint":false,"forwardPage":"","cutPowerTxt":"Trennen Sie zunächst den FRITZ!Repeater für mindestens eine Minute vom Strom und kehren Sie auf diese Seite zurück, nachdem Ihr FRITZ!Repeater neu gestartet ist.","facWhatNextTxt":"Nach dem Zurücksetzen werden Sie automatisch auf die Übersichtsseite des FRITZ!Repeaters weitergeleitet.","facPationsTxt":"Es kann bis zu 5 Minuten dauern, bis der FRITZ!Repeater wieder erreichbar ist, bitte haben Sie etwas Geduld.","showUser":true,"logoutTxt":"\"Sie haben sich erfolgreich von dem FRITZ!Repeater abgemeldet.\"","ifSetFacTxt":"Wenn Sie Ihr Kennwort vergessen haben, kann die Benutzeroberfläche erst dann wieder geöffnet werden, wenn der FRITZ!Repeater auf die Werkseinstellungen zurückgesetzt wurde.","facIsSetTxt":"Der FRITZ!Repeater wird auf Werkseinstellungen zurückgesetzt und startet anschließend neu. Alle Verbindungen gehen dabei kurz verloren.","changedPassTxt":"\"Das Kennwort wurde geändert.\"","txt":{"forgotPassword":"Kennwort vergessen?","loginWithPassword":"Sie können sich auch %1%showPasswordLink%nur mit dem FRITZ!Box-Kennwort anmelden%\/1%showPasswordLink%.","facOnAllowedComp":"Das Wiederherstellen der Werkseinstellungen starten Sie von einem Computer aus, für den die Internetnutzung in der FRITZ!Box unbegrenzt ist.","pleaseChoose":"Bitte wählen ...","facNotSet":"FRITZ!Repeater wurde nicht auf Werkseinstellungen zurückgesetzt","notAuthorized":"Sie sind momentan als Benutzer %1%Name% angemeldet. Dieser Benutzer hat keine Berechtigung, auf die von Ihnen angeforderten FRITZ!Repeater-Inhalte zuzugreifen.","autoLogoutLoginAgain":"Sie wurden automatisch abgemeldet, bitte melden Sie sich erneut an.","pushNotWorking":"Push Service funktioniert nicht?","sendLoginLink":"Zugangslink senden","pushLoginRestartExplain":"Zur Sicherheit ist die Anmeldung an Ihrer FRITZ!Box nur in einem vorgegebenen Zeitraum möglich. Dieser Zeitraum wurde überschritten.","hint_headline":"Hinweis:","waitMore":"Bitte warten Sie %1 Sekunden.","facNotAllowed":"Das Wiederherstellen der Werkseinstellungen ist gescheitert, da dieser Computer nicht dazu berechtigt ist.","pushLoginRestartBtn":"Anmeldevorgang starten","waitOne":"Bitte warten Sie 1 Sekunde.","loginWithAnotherUser":"Sie können sich auch %1%showUsersLink%mit Ihrem Benutzernamen und Kennwort anmelden%\/1%showUsersLink%.","chooseUsername":"Bitte geben Sie einen Benutzernamen an.","sendPushServiceMail":"Push Service Mail senden","facLoseSettings":"Beachten Sie bitte, dass beim Zurücksetzen alle Ihre Einstellungen verloren gehen!","mistypedOrNotAuthorized":"Haben Sie sich vielleicht vertippt oder fehlt Ihnen die Zugangsberechtigung für diesen Bereich?","pushLoginRestartRequest":"Bitte starten Sie erneut den Anmeldevorgang.","defaultUserHint":"Automatisch angelegter Benutzer. Sie können sich mit dem FRITZ!Box-Kennwort anmelden.","login":"Anmelden","loginMailSent":"Die E-Mail mit den Zugangsdaten zur Benutzeroberfläche wurde versendet.","waitTryAgain":"Bitte melden Sie sich erneut an.","loginAgainUserPass":"Für die Anmeldung sind die Anmeldedaten Ihrer FRITZ!Box erforderlich","caution":"Achtung","facRepeat":"Sie können dann die Werkseinstellungen erneut wiederherstellen.","boxPassword":"FRITZ!Box-Kennwort","loginFailed":"Anmeldung fehlgeschlagen.","user":"Benutzername","autoLogoutTimeout":"Sie wurden automatisch abgemeldet, da seit längerer Zeit keine Aktivität registriert wurde.","facDisconnectPower":"Trennen Sie den FRITZ!Repeater für mindestens eine Minute von der Stromversorgung. Nach einer weiteren Minute können Sie erneut auf die Benutzeroberfläche zugreifen. Klicken Sie dann auf \"Zur Übersicht\".","pass":"Kennwort","facNotAllowedOr10Min":"Sie haben keine Berechtigung diese Aktion durchzuführen oder Ihr FRITZ!Repeater ist schon länger als 10 Minuten in Betrieb.","setFacDefaults":"Werkseinstellungen wiederherstellen","choose":"OK","loginBoxPassword":"Für die Anmeldung ist das Kennwort Ihrer FRITZ!Box erforderlich.","repeaterPassword":"FRITZ!Repeater-Kennwort","tooManyLogins":"Es wurden zu viele Sitzungen gleichzeitig gestartet.","pushNeedsWan":"Für den Versand einer Push Service Mail benötigt Ihr FRITZ!Repeater eine aktive Internetverbindung.","loginLinkMailPossible":"Wenn Sie Ihr Kennwort für die Benutzeroberfläche vergessen haben, können Sie sich einen Zugangslink per Push Service Mail senden lassen.","facFailed":"Das Wiederherstellen der Werkseinstellungen ist gescheitert."},"defaultPassword":false,"activeUsers":[{"value":"Udo55","text":"Udo55"},{"value":"Udo2","text":"Udo2"},{"value":"Udo","text":"Udo"}],"pushBtnLogin":false,"fromInternet":false,"pushmailEnabled":true,"sid":"0000000000000000"};
    if (window.gNbc) {
      data.nbc = true;
    }
    login.init(data);
  </script>
</body>
</html>

https://www.swisstransfer.com/dl/01a0c3ba-97b7-701f-a461-767d9c6abf30

<!DOCTYPE html>
<html lang="de">
<head>
  <meta http-equiv=content-type content="text/html; charset=utf-8" />
<meta http-equiv="Cache-Control" content="private, no-transform" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="format-detection" content="telephone=no" />
<meta http-equiv="x-rim-auto-match" content="none" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes, minimal-ui" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta http-equiv="cleartype" content="on">
<link rel="icon" href="/favicon.ico" size="16x16"/>
<link rel="icon" href="/icon.svg" type="image/svg+xml"/>
<link rel="icon" href="/icon.png" type="image/png"/>
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="apple-touch-startup-image" href="/apple-touch-icon.png" />
<style>
  @font-face {
    font-family: 'Source Sans Pro';
    font-style: normal;
    font-stretch: normal;
    font-weight: 400;
    src: url('/assets/fonts/SourceSansPro-Regular.woff2') format('woff2');
  }
  @font-face {
    font-family: 'Source Sans Pro';
    font-style: normal;
    font-stretch: normal;
    font-weight: 600;
    src: url('/assets/fonts/SourceSansPro-SemiBold.woff2') format('woff2');
  }
  @font-face {
    font-family: 'Source Sans Pro';
    font-style: normal;
    font-stretch: normal;
    font-weight: 900;
    src: url('/assets/fonts/SourceSansPro-Black.woff2') format('woff2');
  }
  html, input, textarea, keygen, select, button {
    font-family: 'Source Sans Pro', Arial, sans-serif;
    font-size: 100%;
  }
</style>

  <link rel="stylesheet" type="text/css" href="/css/box.css">
  <link rel='stylesheet' type='text/css' href="/css/rd/login.css"/>
  <title>
          FRITZ!Repeater
  </title>
</head>
<body>
  <script>
    var gNbc = false;
  </script>
  <script src="/js/browser.js"></script>
  <script src="/js/vendor.js"></script>
  <script src="/js/box-login.js"></script>
  <script type="module">
    import { setConfig } from "/js/config.js";
    import login from "/js/login.js";
    setConfig({"ZIGBEE":false,"PRODUKT_NAME":"FRITZ!Repeater 1200 AX","GUI_IS_POWERLINE":false,"isDebug":false,"WLAN":{"has_5ghz_band":false,"has_wpa2_wpa3_mixed_support":false,"has_wpa2_support":true,"omit_macfilter":false,"is_triband":false,"has_wpa_tkip_support":false,"is_double_wlan":false,"has_wpa3_support":false,"has_6ghz_band":false,"has_wpa_wpa2_mixed_support":false},"oem":"avm","gu_type":"release","GUI_IS_MESH_SET":false,"GUI_HIDE_TEASER":false,"isPartOfMeshSet":false,"GUI_IS_REPEATER":true,"GUI_IS_GATEWAY":false,"language":"de","GUI_IS_INHAUS_OR_LABBETA":false});
    const data = {"firstTenMin":false,"challenge":"2$60000$5c8062585003a2403789b94fa53ed5af$6000$8d6e116856e0bff5c47558456ed95d3e","blockTime":0,"pageTitle":"Willkommen bei Ihrem FRITZ!Repeater 1200 AX","lastPage":"","hideForgotPasswordLink":true,"loginReason":0,"username":"Udo55","abortConfig":false,"authMode":"2","fallbackRedirectUrl":"http:\/\/192.168.178.2\/","facTitle":"FRITZ!Repeater-Werkseinstellungen","falseUsername":false,"pageTitleProduct":"FRITZ!Repeater 1200 AX","showFactoryPasswordHint":false,"forwardPage":"","cutPowerTxt":"Trennen Sie zunächst den FRITZ!Repeater für mindestens eine Minute vom Strom und kehren Sie auf diese Seite zurück, nachdem Ihr FRITZ!Repeater neu gestartet ist.","facWhatNextTxt":"Nach dem Zurücksetzen werden Sie automatisch auf die Übersichtsseite des FRITZ!Repeaters weitergeleitet.","facPationsTxt":"Es kann bis zu 5 Minuten dauern, bis der FRITZ!Repeater wieder erreichbar ist, bitte haben Sie etwas Geduld.","showUser":true,"logoutTxt":"\"Sie haben sich erfolgreich von dem FRITZ!Repeater abgemeldet.\"","ifSetFacTxt":"Wenn Sie Ihr Kennwort vergessen haben, kann die Benutzeroberfläche erst dann wieder geöffnet werden, wenn der FRITZ!Repeater auf die Werkseinstellungen zurückgesetzt wurde.","facIsSetTxt":"Der FRITZ!Repeater wird auf Werkseinstellungen zurückgesetzt und startet anschließend neu. Alle Verbindungen gehen dabei kurz verloren.","changedPassTxt":"\"Das Kennwort wurde geändert.\"","txt":{"forgotPassword":"Kennwort vergessen?","loginWithPassword":"Sie können sich auch %1%showPasswordLink%nur mit dem FRITZ!Box-Kennwort anmelden%\/1%showPasswordLink%.","facOnAllowedComp":"Das Wiederherstellen der Werkseinstellungen starten Sie von einem Computer aus, für den die Internetnutzung in der FRITZ!Box unbegrenzt ist.","pleaseChoose":"Bitte wählen ...","facNotSet":"FRITZ!Repeater wurde nicht auf Werkseinstellungen zurückgesetzt","notAuthorized":"Sie sind momentan als Benutzer %1%Name% angemeldet. Dieser Benutzer hat keine Berechtigung, auf die von Ihnen angeforderten FRITZ!Repeater-Inhalte zuzugreifen.","autoLogoutLoginAgain":"Sie wurden automatisch abgemeldet, bitte melden Sie sich erneut an.","pushNotWorking":"Push Service funktioniert nicht?","sendLoginLink":"Zugangslink senden","pushLoginRestartExplain":"Zur Sicherheit ist die Anmeldung an Ihrer FRITZ!Box nur in einem vorgegebenen Zeitraum möglich. Dieser Zeitraum wurde überschritten.","hint_headline":"Hinweis:","waitMore":"Bitte warten Sie %1 Sekunden.","facNotAllowed":"Das Wiederherstellen der Werkseinstellungen ist gescheitert, da dieser Computer nicht dazu berechtigt ist.","pushLoginRestartBtn":"Anmeldevorgang starten","waitOne":"Bitte warten Sie 1 Sekunde.","loginWithAnotherUser":"Sie können sich auch %1%showUsersLink%mit Ihrem Benutzernamen und Kennwort anmelden%\/1%showUsersLink%.","chooseUsername":"Bitte geben Sie einen Benutzernamen an.","sendPushServiceMail":"Push Service Mail senden","facLoseSettings":"Beachten Sie bitte, dass beim Zurücksetzen alle Ihre Einstellungen verloren gehen!","mistypedOrNotAuthorized":"Haben Sie sich vielleicht vertippt oder fehlt Ihnen die Zugangsberechtigung für diesen Bereich?","pushLoginRestartRequest":"Bitte starten Sie erneut den Anmeldevorgang.","defaultUserHint":"Automatisch angelegter Benutzer. Sie können sich mit dem FRITZ!Box-Kennwort anmelden.","login":"Anmelden","loginMailSent":"Die E-Mail mit den Zugangsdaten zur Benutzeroberfläche wurde versendet.","waitTryAgain":"Bitte melden Sie sich erneut an.","loginAgainUserPass":"Für die Anmeldung sind die Anmeldedaten Ihrer FRITZ!Box erforderlich","caution":"Achtung","facRepeat":"Sie können dann die Werkseinstellungen erneut wiederherstellen.","boxPassword":"FRITZ!Box-Kennwort","loginFailed":"Anmeldung fehlgeschlagen.","user":"Benutzername","autoLogoutTimeout":"Sie wurden automatisch abgemeldet, da seit längerer Zeit keine Aktivität registriert wurde.","facDisconnectPower":"Trennen Sie den FRITZ!Repeater für mindestens eine Minute von der Stromversorgung. Nach einer weiteren Minute können Sie erneut auf die Benutzeroberfläche zugreifen. Klicken Sie dann auf \"Zur Übersicht\".","pass":"Kennwort","facNotAllowedOr10Min":"Sie haben keine Berechtigung diese Aktion durchzuführen oder Ihr FRITZ!Repeater ist schon länger als 10 Minuten in Betrieb.","setFacDefaults":"Werkseinstellungen wiederherstellen","choose":"OK","loginBoxPassword":"Für die Anmeldung ist das Kennwort Ihrer FRITZ!Box erforderlich.","repeaterPassword":"FRITZ!Repeater-Kennwort","tooManyLogins":"Es wurden zu viele Sitzungen gleichzeitig gestartet.","pushNeedsWan":"Für den Versand einer Push Service Mail benötigt Ihr FRITZ!Repeater eine aktive Internetverbindung.","loginLinkMailPossible":"Wenn Sie Ihr Kennwort für die Benutzeroberfläche vergessen haben, können Sie sich einen Zugangslink per Push Service Mail senden lassen.","facFailed":"Das Wiederherstellen der Werkseinstellungen ist gescheitert."},"defaultPassword":false,"activeUsers":[{"value":"Udo55","text":"Udo55"},{"value":"Udo2","text":"Udo2"},{"value":"Udo","text":"Udo"}],"pushBtnLogin":false,"fromInternet":false,"pushmailEnabled":true,"sid":"0000000000000000"};
    if (window.gNbc) {
      data.nbc = true;
    }
    login.init(data);
  </script>
</body>
</html>

#2
TabletUI / Aw: Probleme mit ftui3 seit de...
Letzter Beitrag von Prof. Dr. Peter Henning - 21 September 2026, 13:18:22
Zitat von: setstate am 20 September 2026, 21:09:08Funktioniert den ./examples/grid.html ?
Ja.

Ich habe jetzt eine wahrscheinliche Ursache gefunden.
In die betreffende Seite binde ich folgendes JavaScript ein:

const ftui_pv1_power    = () => input => pv1_power(input);
function pv1_power(power) {
    var a = document.getElementById('pv1a');
    var b = document.getElementById('pv1b');
    var c = document.getElementById('pv1c');
    var s;
    if (power > 0.0) {
        s = "url(#g_v_d)";
    } else {
        s = "url(#b_s)";
    }
    a.style.fill = s;
    b.style.fill = s;
    c.style.fill = s;
    return power;
}

Die pipeline Funktion ist also eigentlich nur ein "Durchlauferhitzer", die den Datenwert von Power einfach durchreicht. Allerdings zwischendrin - je nach Wert - ein fill-Pattern für ein anderes Element umschießt. Genauer ist das die Laufrichtung einer Animation.

In der Seite wird das dann verwendet als
<ftui-label class="size-1" [text]="nt5000:Pac | fix(2) | ftui_pv1_power()">
                <span slot="unit" class="size--2">kW</span>
            </ftui-label>
Und genau das funktioniert nicht mehr, dieses Label bleibt leer - und die eingeblendete Seite wird ausgegraut.

LG

pah
#3
Solaranlagen / Aw: 76_SolarForecast - Informa...
Letzter Beitrag von DS_Starter - 21 September 2026, 13:11:13
Hallo enno,

die Warnung habe ich beseitigt und die Funktion _createReadingsFromArrayFast entsprechend gefixt.
Fix liegt in V 2.10.5 in meinem contrib vorab.

LG,
Heiko
#4
FHEM Code changes / Revision 31672: 76_SolarForeca...
Letzter Beitrag von System - 21 September 2026, 13:10:24
Revision 31672: 76_SolarForecast: contrib Version 2.10.5

76_SolarForecast: contrib Version 2.10.5

Source: Revision 31672: 76_SolarForecast: contrib Version 2.10.5
#5
FRITZ!Box / Aw: FritzSmart mit Fritz Labor...
Letzter Beitrag von JoWiemann - 21 September 2026, 13:01:17
Zitat von: roelleke am 21 September 2026, 10:22:30Hallo,
ich habe die Version von dem obigen Link ausprobiert, aber sie führt zu dem gleichen Fehler. Die alte Version '31628 2026-09-07 13:16:46Z' funktioniert hingegen einwandfrei.

Gruß Dieter
Hallo Dieter,
danke für das Probieren. Ohne das Log und einem List komme ich allerdings nicht weiter. Auch, da einige Sachen noch experimentell sind, solange Fritz noch in der Laborphase ist.

Grüße Jörg
#6
Wallboxen und E-Fahrzeuge / Aw: RenaultZE
Letzter Beitrag von Prof. Dr. Peter Henning - 21 September 2026, 12:57:15
Zitat von: fred_feuerstein am 20 September 2026, 19:40:06Nochmal zurück zur Location. Meine Alpine A290 meldet eigentlich immer die aktuelle Parkposition als Koordinaten. Was manchmal nicht passt, ist die übermittelte Info ob zuhause (home) oder nicht zuhause (away) mit komischer Entfernungsangabe zu "home".
Das ist genau der Punkt: Nach (noch) unbekannten Kriterien wird das mal und mal nicht veröffentlicht. Insofern meine algorithmische Lösung: Wenn sich der Kilometerstand seit der letzten Parkposition geändert hat, und für mehr als x Minuten gleich bleibt, steht die Kiste zuhause.

LG

pah
#7
Sonstiges / Aw: MQTT best current practice
Letzter Beitrag von TomLee - 21 September 2026, 12:43:52
Zitat von: rudolfkoenig am 18 September 2026, 12:57:20
Zitatb) Ich hatte gestern ein paar harte Abstürze beim Versuch, "reload MQTT2_DEVICE" abzusetzen.
Da hat wer in den Clients Eintrag eines Moduls, was Nachrichten per Dispatch verteilt, Muell eingebaut.
Ich tippe auf MQTT2_DISCOVERY, da wird oefters das clientOrder Attribut des IODevs gesetzt.
MQTT2_CLIENT/MQTT2_SERVER pruefen nicht beim Setzen des Attributes, ob der Inhalt wenigstens Formal korrekt ist, das koennte ich noch einbauen.


Theorie:

Nachstellen, ohne .clientArray anzufassen:

1. Modul nehmen, das in clientOrder steht, hier MQTT2_DISCOVERY.
2. In dessen Initialize $hash->{Match} und $hash->{ParseFn} verschreiben, etwa Mtach und PraseFn. Datei bleibt syntaktisch gültig.
3. reload 10_MQTT2_DISCOVERY  meldet keinen Fehler. Danach sind beide Einträge undef, .clientArray enthält den Modulnamen weiter.
4. Irgendeine MQTT-Nachricht schicken.

PERL WARNING: Use of uninitialized value in regexp compilation at fhem.pl line 4195.
Can't use an undefined value as a subroutine reference at fhem.pl line 4203.

FHEM beendet sich. Dasselbe passiert mit nur verschriebenem ParseFn, dann kommt nur Zeile 4203.

Der Cache ist dabei nicht schuld: CommandReload ersetzt den Moduleintrag durch das, was Initialize gefüllt hat, und computeClientArray prüft nur auf Match. Ein Tippfehler beim Bearbeiten eines Client-Moduls reicht also, um FHEM zu beenden. next if(!$modules{$m}{ParseFn}); in der Schleife wäre eine Möglichkeit.
#8
SVG / Plots / logProxy / Ergänzungen zu plotAsPng und F...
Letzter Beitrag von Prof. Dr. Peter Henning - 21 September 2026, 12:34:12
Hallo Rudi,

hier meine Vorschläge.

1. in Zeile 2029 ist by x= ... ein "'" zuviel. Statt
SVG_pO sprintf("<rect x='%d'' y='%d' width='%d' height='%d' $attr/>",muss es heißen
SVG_pO sprintf("<rect x='%d' y='%d' width='%d' height='%d' $attr/>",
2.Die beim Zeichnen von Symbolen verwendete sprintf-Funktion wirft eine Warnungsmeldung
Zitat2026.09.21 11:45:09 1: PERL WARNING: Invalid conversion in sprintf: "%"" at /opt/fhem/FHEM/98_SVG.pm line 2061.
(bzw. mit anderen Zeilennummern, wenn das Symbol kein Diamond ist) aus, wenn in einem Label des Plots ein "%"-Zeichen auftaucht, und dieses Label dann in der Legende verwendet wird. Die Darstellung ist zwar korrekt, aber die Warnungsmeldung müsste nicht sein. Dazu muss bei den Symbolen (außer circle) das $attr aus dem ersten Argument sprintf herausgenommen werden und durch ein "%s" ersetzt werden,
$attr wird dann als weiterer Parameter übergeben. Also ab Zeile 2007
if ($lType =~ /^points(:([a-z]+))?(:([\d.]+))?/) {

  my $pShape = $2 ? $2 : "di";
  my $pSize  = $4;

  if(!$pSize) { # if not defined, use the line-width as size
    $attributes =~ s/stroke-width:(\d+)/stroke-width:1/;
    $pSize = $1 && $1 >= 2 ? $1 : 3;
  }

  foreach my $i (0..int(@{$dxp})-1) {
    my ($x1, $y1) = (int($x+$dxp->[$i]),
                     int($y+$h-($dyp->[$i]-$min)*$hmul));
    next if($x1 == $lx && $y1 == $ly);
    $lx = $x1; $ly = $y1;

    my $attr = "$attributes $lStyle".($isFill ? "" : ' fill="none"');

    if ($pShape eq "circle") {
      SVG_pO "<circle cx='$x1' cy='$y1' r='$pSize' $attr/>";

    } elsif ($pShape eq "square") {
      my $d = $pSize * 2;
      SVG_pO sprintf(
        "<rect x='%d' y='%d' width='%d' height='%d' %s/>",
        $x1-$pSize, $y1-$pSize, $d, $d, $attr
      );

    } elsif ($pShape eq "triangleup") {
      SVG_pO sprintf(
        "<polygon points='%d,%d %d,%d %d,%d' %s/>",
        $x1,           $y1-$pSize,
        $x1-$pSize,    $y1+$pSize,
        $x1+$pSize,    $y1+$pSize,
        $attr
      );

    } elsif ($pShape eq "triangledown") {
      SVG_pO sprintf(
        "<polygon points='%d,%d %d,%d %d,%d' %s/>",
        $x1-$pSize,    $y1-$pSize,
        $x1+$pSize,    $y1-$pSize,
        $x1,           $y1+$pSize,
        $attr
      );

    } elsif ($pShape eq "plus") {
      SVG_pO sprintf(
        "<line x1='%d' y1='%d' x2='%d' y2='%d' %s/>",
        $x1-$pSize, $y1, $x1+$pSize, $y1, $attr
      );
      SVG_pO sprintf(
        "<line x1='%d' y1='%d' x2='%d' y2='%d' %s/>",
        $x1, $y1-$pSize, $x1, $y1+$pSize, $attr
      );

    } elsif ($pShape eq "cross") {
      SVG_pO sprintf(
        "<line x1='%d' y1='%d' x2='%d' y2='%d' %s/>",
        $x1-$pSize, $y1-$pSize,
        $x1+$pSize, $y1+$pSize,
        $attr
      );
      SVG_pO sprintf(
        "<line x1='%d' y1='%d' x2='%d' y2='%d' %s/>",
        $x1+$pSize, $y1-$pSize,
        $x1-$pSize, $y1+$pSize,
        $attr
      );

    } elsif ($pShape eq "minus") {
      SVG_pO sprintf(
        "<line x1='%d' y1='%d' x2='%d' y2='%d' %s/>",
        $x1-$pSize, $y1, $x1+$pSize, $y1, $attr
      );

    } else { # diamond
      SVG_pO sprintf(
        "<polygon points='%d,%d %d,%d %d,%d %d,%d %d,%d' %s/>",
        $x1-$pSize, $y1,
        $x1,        $y1-$pSize,
        $x1+$pSize, $y1,
        $x1,        $y1+$pSize,
        $x1-$pSize, $y1,
        $attr
      );
    }
  }
}

3. Die Funktion plotAsPng macht etwas Schwierigkeiten, die in der libRSVG-library begründet liegen.
a.) Sie kommt mit CSS-Variablen nicht zurecht. Diese sind aber in CSS-Files sehr praktisch, weil man damit in CSS-Dateien den Wartungsaufwand drastisch verringert. Beispielsweise müssen Farben nur einmal angegeben werden und können dann referenziert werden
 
  --svg-l0: red;
  --svg-l1: green;
  --svg-l2: blue;
.SVGplot.l0 { stroke: var(--svg-l0); }
.SVGplot.l1 { stroke: var(--svg-l1); }
.SVGplot.l2 { stroke: var(--svg-l2); }

b.) Sie ignoriert die Festlegung von Schriftfamilie und Schriftgröße.

c.) Die erzeugten PNG-Dateien sind nicht skalierbar, sondern haben die durch das FHEM-Attribut plotsize festgelegte Größe.

Zur Behebung dieser drei Schwächen muss man zunächst die erzeugte SVG-Datei bearbeiten, dafür gibt es drei neue Helperfunktionen
##################
# Helper function to replace CSS Vars

sub SVG_resolveCssVars($) {
    my ($svg) = @_;

    my %vars;

    # CSS Custom Properties aus :root lesen
    if($svg =~ /:root\s*\{(.*?)\}/s) {
        my $root = $1;

        while($root =~ /--([\w-]+)\s*:\s*([^;]+)\s*;/g) {
            $vars{$1} = $2;
        }
    }

    # var(--name) durch den gefundenen Wert ersetzen
    $svg =~ s{
        var\(--([\w-]+)\)
    }{
        exists($vars{$1}) ? $vars{$1} : "var(--$1)"
    }gex;

    return $svg;
}

##################
# Helper function to fix SVG fonts

sub SVG_fixLibRSVGFonts($) {
    my ($svg) = @_;

    my $fontFamily;

    if($svg =~ /(?:^|\})\s*text\s*\{([^}]*)\}/s) {
        my $css = $1;

        if($css =~ /font-family\s*:\s*([^;!]+)(?:\s*!important)?\s*;/i) {
            $fontFamily = $1;
            $fontFamily =~ s/^\s+|\s+$//g;
        }
    }

    return $svg if(!defined($fontFamily) || $fontFamily eq "");

    # XML-Attribut sicher quoten
    $fontFamily =~ s/&/&amp;/g;
    $fontFamily =~ s/"/&quot;/g;

    $svg =~ s{
        <text\b
    }{
        qq{<text font-family="$fontFamily"}
    }gex;

    return $svg;
}

##################
# Helper function to scale SVG

sub SVG_scaleForLibRSVG($$$) {
    my ($svg, $newWidth, $newHeight) = @_;

    return $svg
        if($svg !~ /<svg\b[^>]*\bwidth=['"]([\d.]+)(?:px)?['"][^>]*\bheight=['"]([\d.]+)(?:px)?['"]/s);

    my ($oldWidth, $oldHeight) = ($1, $2);

    $svg =~ s{<svg\b([^>]*)>}{
        my $attr = $1;

        $attr =~ s/\bwidth=['"][^'"]+['"]/width="${newWidth}px"/;
        $attr =~ s/\bheight=['"][^'"]+['"]/height="${newHeight}px"/;

        $attr =~ s/\s+viewBox=['"][^'"]*['"]//;

        $attr =~ s/width\s*:\s*[\d.]+px/width:${newWidth}px/;
        $attr =~ s/height\s*:\s*[\d.]+px/height:${newHeight}px/;

        qq{<svg$attr viewBox="0 0 $oldWidth $oldHeight">};
    }ex;

    return $svg;
}
In der Funktion plotAsPng werden diese drei Helperfunktionen gerufen, bevor die SVG-Datei an die libRSVG übergeben wird. Nach "($mimetype, $svgdata)   = SVG_showLog("unused");" wird also der Code geändert zu

   
  my ($w, $h) = split(",", AttrVal($svgName, "plotsize", "800,160"));
  $svgdata =~ s/<\/svg>/<polyline opacity="0" points="0,0 $w,$h"\/><\/svg>/;

  # Forum #32791,#116138: some lib versions cannot parse complex CSS selectors
  $svgdata =~ s/\.SVGplot\./\./g if(AttrVal($svgName, "plotAsPngFix", 0));
  $svgdata = Encode::decode("UTF-8", $svgdata) if(!$unicodeEncoding); #129693
 
  #-- CSS Custom Properties fuer LibRSVG aufloesen
  $svgdata = SVG_resolveCssVars($svgdata);
 
  #-- Fix fonts
  $svgdata = SVG_fixLibRSVGFonts($svgdata);
 
  #-- target width as fourth parameter for output as png
  my $targetWidth         = $plotName[3];
  if($targetWidth) {
    my $targetHeight = int($h * $targetWidth / $w + 0.5);

    $svgdata = SVG_scaleForLibRSVG(
        $svgdata,
        $targetWidth,
        $targetHeight
    );
  }

Die gewünschte Zielbreite der PNG-Datei wird einfach als 4. Parameter an plotAsPng übergeben.

Und schließlich habe ich noch eine weitere Helperfunktion, die eigentlich das Ziel der ganzen Sache war. Dieser gebe ich als ersten Parameter den Namen eines FHEM SVG-Device, als zweiten Parameter den Namen der PNG-Datei, und als dritten Parameter die horizontale Auflösung in Pixeln.
###############################################################################
#
#  plot2png
#
###############################################################################

sub plot2png($$$) {
    my ($plot, $file, $width) = @_;

    my $png = plotAsPng($plot, undef, undef, $width);
    return "plotAsPng failed" if(!defined($png));

    open(my $fh, ">", $file)
        or return "Cannot write $file: $!";

    binmode($fh);
    print $fh $png;
    close($fh);

    return $file;
}

Ob man das auch als Ausgabeoption in 98_SVG.pm einbaut, lasse ich offen.

Die komplett geänderte 98_SVG.pm hänge ich zum Testen an. Achtung: Diese Datei enthält in plotAsPng noch einen überflüssigen Block, der mir die komplett erzeugte SVG nach /tmp geschrieben hat.

LG

pah

P.S.: Bevor jemand fragt, warum ich das nicht als Patchdatei liefere: Code-Review...


#9
TabletUI / Aw: Darstellung Sonnenbatterie
Letzter Beitrag von mr_petz - 21 September 2026, 11:53:08
okay gemerged.
entschuldigung für die späte rückmeldung
#10
Solaranlagen / Aw: 76_SolarForecast - Informa...
Letzter Beitrag von enno - 21 September 2026, 11:23:47
Moin,

ich bekomme stündlich folgende Warnung: PERL WARNING: Use of uninitialized value in string ne at fhem.pl line 5140.
2026.09.21 11:00:05.101 1: stacktrace:
2026.09.21 11:00:05.101 1:     main::__ANON__                      called by fhem.pl (5140)
2026.09.21 11:00:05.102 1:     main::readingsBulkUpdate            called by ./FHEM/76_SolarForecast.pm (36313)
2026.09.21 11:00:05.102 1:     FHEM::SolarForecast::_createReadingsFromArrayFast called by ./FHEM/76_SolarForecast.pm (12788)
2026.09.21 11:00:05.102 1:     FHEM::SolarForecast::__ANON__       called by ./FHEM/76_SolarForecast.pm (12828)
2026.09.21 11:00:05.102 1:     FHEM::SolarForecast::_ctStepTiming  called by ./FHEM/76_SolarForecast.pm (12788)
2026.09.21 11:00:05.102 1:     FHEM::SolarForecast::centralTask    called by ./FHEM/76_SolarForecast.pm (12499)
2026.09.21 11:00:05.102 1:     FHEM::SolarForecast::runTask        called by fhem.pl (4012)
2026.09.21 11:00:05.102 1:     main::CallFn                        called by fhem.pl (855)

Für die Suche habe ich mir an der Stelle ein Log eingebaut. Das sagt mir: SolarForecast DEBUG bulkUpdate: reading=[pvCorrectionFactor_11] new=[0.96 (automatic - old factor: 0.77, AI result used, Sun Alt range: 30, Cloud range: 75, Days in range: 4)] old=<undef> elem=[pvCorrectionFactor_11<>0.96 (automatic - old factor: 0.77, AI result used, Sun Alt range: 30, Cloud range: 75, Days in range: 4)] Die Warnung kommt wohl vom fehlenden old=<undef>. Was kann ich tun, um das gerade zu ziehen?

Gruss
  Enno