Hauptmenü

Ausführung DOIF subs block

Begonnen von dw82, 09 Juli 2025, 18:32:56

Vorheriges Thema - Nächstes Thema

dw82

Hallo, unter https://wiki.fhem.de/wiki/DOIF/Perl-Modus ist ja der DOIF subs block dokumentiert. Mich würde interessieren, wann über welchen Mechanismum dieser Block ausgeführt wird, damit die darin definierten Funktionen zur Verfügung stehen.
Ich hatte nämlich jetzt das Problem, dass ich im Hauptblock HttpUtils_NonblockingGet verwendet habe mit einem Callback, der im DOIF subs block definiert wurde. Schon beim Testen war mir aufgefallen, dass ich explicit block_01 aufrufen musste, damit Änderungen im Callback auch wirksam wurden. Jetzt habe ich jedoch das Problem festgestellt, dass wenn FHEM neugestartet wird, der Block anscheinend gar nicht asugeführt wird, die Funktionsdefinition nicht zur Verfügung steht und, wenn HttpUtils_NonblockingGet aufgerufen wird und den Callback aufrufen möchte, FHEM komplett abschmiert. Äußerst unschön. Wäre eine Definition im init Block eine Alternative? Allerdings stellt sich mir beim init Block die Frage, wie man diesen explizit aufrufen kann, damit Änderungen wirksam werden, wenn man an der Definition des Callbacks etwas geändert hat.

Damian

#1
Der subs-Block wird als erster Block per eval während der Definitionsphase des DOIF-Devices ausgeführt. Darin selbst definierte Funktionen befinden sich im DOIF-Package und können in anderen DOIF-Perlblöcken, die per Event-Trigger oder Zeittrigger ausgeführt werden, unmittelbar genutzt werden. Die eigenen Perlfunktionen sollten alle zum Ausführungszeitpunkt bereits existieren, da Trigger erst nach der Initialisierungsphase des FHEM-Systems kommen können und da sind bereits alle Devices definiert.

Zu beachten ist, dass alle DOIF-Devices den gleichen Namensraum (package DOIF) nutzen. Das bedeutet, dass die Funktionsnamen definiert im subs-Block über alle DOIF-Devices eindeutig sein müssen, sonst werden sie von anderen überschrieben.

Wenn du eine konkrete Definition hast, die nachvollziehbar zu einem Problem führt, dann kannst du sie hier posten.

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

dw82

#2
Also ich habe jetzt mal ein Minimalbeispiel erstellt. Wenn man die aktuelle FHEM Version auscheckt und ein einziges DOIF mit der Definition

DOIF subs {
  sub callback($) {
    fhem("setreading $SELF callback OK");
  }
}
{
  if ([$SELF:"test"]) {
    my $param = {
      url => "localhost:8083",
      callback => \&callback
    };
    ::HttpUtils_NonblockingGet($param);
  }
}

sowie mit Attribut

setlist test

erstellt, so führt

set ... test

zu

condition c02: Undefined subroutine &DOIF::callback called at FHEM/HttpUtils.pm line 962

Beim ersten Testen konnte ich auch einen Absturz von FHEM bewirken, beim erneuten Ausführen wird die Exception abgefangen und ein entsprechendes Reading erzeugt.
Ich habe jetzt auch einen Workaround gefunden. Ein zusätzlicher erster Block

init {
  fhem_set("$SELF block_02");
}

behebt das Problem. Allerdings wirkt dies auf mich umständlich und ich bin der Meinung, dass der subs Block automatisch beim FHEM-Start (eager) oder der ersten Blockausführung des DOIFs (lazy) ausgeführt werden müsste.
Außerdem sollte er auch nach jedem modify der Definition aufgerufen werden, was anscheinend ebenfalls nicht der Fall ist.

Damian

Es wundert mich, dass es überhaupt funktioniert. Eigentlich müsste man das Package DOIF in HttpUtils per use zuerst bekannt machen.

Ein direkter Aufruf  von callback im block_02 sollte dagegen ohne Probleme funktionieren, denn dort ist DOIF-Package bekannt.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF