DOIF subs aktualisieren und Benennung der Perl-Blöcke

Begonnen von bismosa, 03 April 2024, 20:54:58

Vorheriges Thema - Nächstes Thema

bismosa

Hallo!

Vermutlich stelle ich mich gerade ein wenig dämlich an...aber ich habe 2 Probleme bei der Verwendung von DOIF subs:
Ich nutze das Beispiel:
DOIF subs { ## Definition von Perlfunktionen lamp_on und lamp_off
  sub lamp_on {
     fhem_set("lamp on");
     set_State("on");
  }
  sub lamp_off {
     fhem_set("lamp off");
     set_State("off");
  }
}
{[06:00];lamp_on()}  ## Um 06:00 Uhr wird die Funktion lamp_on aufgerufen
{[08:00];lamp_off()} ## Um 08:00 Uhr wird die Funktion lamp_off aufgerufen

1.) Wenn ich die Definition in den subs ändere, muss ich entweder FHEM neu starten oder den ersten Block 1x ausführen, damit die Änderungen auch übernommen werden? Ist das so korrekt?

2.) Wenn ich eine Benennung vor den Funktionsaufrufen (Perl-Blöcken) einfüge, bekomme ich eine Fehlermeldung:
condition c01: Subroutine lamp_off redefined
Wenn ich eine Benennung nutze, habe ich auch keine Möglichkeit mehr (ohne FHEM Neustart) die DOIF subs zu aktualisieren.
Ist das ein gewolltes verhalten? Ich nutze eigentlich gerne eine Benennung der Funktionen. Das macht die Bedienung angenehmer  :)

Ein Workaround könnte so sein (extra geschweifte Klammern...also ein leerer Perl Block nach den subs):
DOIF subs { ## Definition von Perlfunktionen lamp_on und lamp_off
  sub lamp_on {
     fhem_set("lamp on");
     set_State("on");
  }
  sub lamp_off {
     fhem_set("lamp off");
     set_State("off");
  }
}
{}
Lampe_an{[06:00];lamp_on1()}  ## Um 06:00 Uhr wird die Funktion lamp_on aufgerufen
Lampe_aus{[08:00];lamp_off1()} ## Um 08:00 Uhr wird die Funktion lamp_off aufgerufen
Dann kann ich auch wieder block_01 ausführen um die subs zu aktualisieren...

Gruß
Bismosa
1x nanoCUL 433MHz (SlowRF Intertechno) für Fenstersensoren
1x nanoCUL 868Mhz für MAX (9x HT 1xWT)
1x ZigBee CUL
Weiteres: Squeezebox server, Kindle Display, ESP8266, Löterfahrung, ...

Damian

Wenn du per DEF etwas änderst, dann werden alle subs im DOIF-Devices des Blocks subs aktualisiert. Redefined ist dann die Meldung des Systems, ein Neustart ist nicht erforderlich.

Alle subs, die du in irgendwelchen DOIFs definierst, liegen im gleichen Package namens DOIF.

Man muss also auf eindeutige Namen achten, sonst überschreiben sich die Subroutinen gegenseitig - die letzte gewinnt. Das Problem kann man umgehen, indem man z. B. beim Namen der Subroutine $SELF einbaut, um sie eindeutig zu machen z. B. $SELF_lamp_on.

Das ist, denke ich, hier aber nicht das Problem, sollte man aber im Hinterkopf behalten, falls man öfters Subroutinen im subs-Block definiert.


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

Damian

Ich habe es bei mir mit:

defmod di_subs DOIF subs { sub test {set_Reading("test",0)}}\
{test()}

getestet.

Nach der Definition und Ausführung des Blocks block_01 wird das Reading "test" auf 0 gesetzt.

Wird die Definition per DEF-modify geändert, z. B. auf {set_Reading("test",1)}, so wird durch das Ausführen des Blocks block_01 das Reading auf 1 gesetzt. Das System musste nicht durchgestartet werden.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

bismosa

#3
Hallo!

Dann ist das ja ein gewolltes verhalten, das ich den "block_01" einmal ausführen muss um das zu aktualisieren.
Wenn man das weiß, ist es ja kein Problem mehr  :)

Allerdings bleibt das Problem, das man kein "block_01" zum ausführen hat, wenn man die weiteren Blöcke benannt hat. Z.B:
defmod di_subs DOIF subs { sub test {set_Reading("test",0)}}\
test{test()}
Dann kann ich zwar "test" ausführen, ein block_01 gibt es dann aber nicht mehr.
Mit dem Workaround mit
defmod di_subs DOIF subs { sub test {set_Reading("test",0)}}\
{}
test{test()}
Klappt es jedoch problemlos.

Aktuell versuche ich eine Funktion für Zählerstände in einem DOIF so zu integrieren, dass ich auch aus anderen DOIF diese Funktion benutzen kann um Readings zu aktualisieren.
Das klappt auch. Allerdings habe ich gerade den Fall, dass ich gerne auf alle Readings des Devices zurückgreifen möchte.
Mittels

foreach my $rname (keys %{$hash->{READINGS}}) {
Komme ich nur an die Readings von dem DOIF, in dem die Funktion enthalten ist.
Deswegen versuche ich mittels

my $devhash=$::defs->{'$dname'};
foreach my $rname (keys %{$devhash->{READINGS}}) {
dort heran zu kommen. $dname ist eine übergebene Variable an die Funktion mit dem DeviceNamen.
Kannst Du mir hier einen Tipp geben?


[edit]
Da bastelt man den ganzen Nachmittag und findet den Fehler einfach nicht  ::)
Ich habe es nun geschafft mit:
my $devhash=$::defs{$dname};
foreach my $rname (keys %{$devhash->{READINGS}}) {
[/edit]

Danke!

Gruß
Bismosa
1x nanoCUL 433MHz (SlowRF Intertechno) für Fenstersensoren
1x nanoCUL 868Mhz für MAX (9x HT 1xWT)
1x ZigBee CUL
Weiteres: Squeezebox server, Kindle Display, ESP8266, Löterfahrung, ...

Damian

Der block_01 oder test, wie du ihn jetzt benannt hast, war nur dazu da, zu zeigen, dass die in subs definierte Funktion test nach der Änderung korrekt funktioniert. Diese Blöcke sind nicht erforderlich, um eine geänderte Funktion (Subroutine) zu nutzen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

bismosa

Hallo,

ich glaube ich habe mich nicht richtig ausgedrückt. Sorry.
Wenn ich einen benannten Block direkt nach dem Block "DOIF subs" einfüge, habe ich nicht mehr die Möglichkeit den "block_01" (subs) auszuführen. Das verschwindet dann aus dem set Befehl.
Bei:
defmod di_subs DOIF subs { sub test {set_Reading("test",0)}}\
test{test()}
Habe ich nur noch "test", "enable" und "disable" im Set-Befehl zur Verfügung.

Mit:
defmod di_subs DOIF subs { sub test {set_Reading("test",0)}}\
{}
test{test()}
habe ich richtigerweise "block_01","block_02","test","enable","disable" zur Verfügung.

Das ist mir heute noch aufgefallen:
Ich musste meinen Raspberry heute neu starten. Dabei wurden die subs gar nicht erst geladen? Ich muss bei einem Neustart den "block_01" erst ausführen.
Habe ich hier in der Doku etwas übersehen?

Gruß
Bismosa
1x nanoCUL 433MHz (SlowRF Intertechno) für Fenstersensoren
1x nanoCUL 868Mhz für MAX (9x HT 1xWT)
1x ZigBee CUL
Weiteres: Squeezebox server, Kindle Display, ESP8266, Löterfahrung, ...

Damian

Zitat von: bismosa am 07 April 2024, 13:41:21Hallo,

ich glaube ich habe mich nicht richtig ausgedrückt. Sorry.
Wenn ich einen benannten Block direkt nach dem Block "DOIF subs" einfüge, habe ich nicht mehr die Möglichkeit den "block_01" (subs) auszuführen. Das verschwindet dann aus dem set Befehl.
Bei:
defmod di_subs DOIF subs { sub test {set_Reading("test",0)}}\
test{test()}
Habe ich nur noch "test", "enable" und "disable" im Set-Befehl zur Verfügung.

Mit:
defmod di_subs DOIF subs { sub test {set_Reading("test",0)}}\
{}
test{test()}
habe ich richtigerweise "block_01","block_02","test","enable","disable" zur Verfügung.

Das ist mir heute noch aufgefallen:
Ich musste meinen Raspberry heute neu starten. Dabei wurden die subs gar nicht erst geladen? Ich muss bei einem Neustart den "block_01" erst ausführen.
Habe ich hier in der Doku etwas übersehen?

Gruß
Bismosa

Ich verstehe das Problem nicht. block_01 gibt des doch nur, wenn es auch einen unbenannten Block gibt. Wenn du keinen unbenannten Block hast, kannst auch keinen block_01 geben, sondern nur die benannten.

Der subs-Block wird immer bei der Definition ausgeführt und damit auch beim Neustart. Die Definition einer Subroutine bedeutet natürlich nicht gleichzeitig, dass sie ausgeführt wird, vielleicht ist das dein Verständnisproblem.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

bismosa

Hallo!

1.) Das "problem" ist eigentlich nur, dass es kein "block_01" zum aktualisieren der subs gibt, wenn es danach nur benannte Blöcke gibt.
Deswegen hatte ich nie die Vermutung, das ich nach einer Aktualisierung der subs den "block_01" ausführen könnte, um den Code auch zu aktualisieren. (Ich nutze immer benannte Blöcke)

Das ganze ist meiner Meinung nach nur ein Schönheitsfehler. Muss man halt wissen.  :)

2.) Das Problem, das die Funktionen subs bei mir nach einem Neustart nicht verfügbar sind, ist reproduzierbar. Die Funktionen sind erst nach dem Ausführen von "block_01" vorhanden.
Ausgeführt werden sollen die Funktionen nicht beim Neustart.  ;)
Kann es sein, das es nur funktioniert, wenn es nur ein DOIF mit "subs" gibt? Ich sehe gerade, das ein anderes DOIF nach dem Neustart funktioniert...

Gruß
Bismosa
1x nanoCUL 433MHz (SlowRF Intertechno) für Fenstersensoren
1x nanoCUL 868Mhz für MAX (9x HT 1xWT)
1x ZigBee CUL
Weiteres: Squeezebox server, Kindle Display, ESP8266, Löterfahrung, ...

Damian

Zitat von: bismosa am 07 April 2024, 17:15:43Hallo!

1.) Das "problem" ist eigentlich nur, dass es kein "block_01" zum aktualisieren der subs gibt, wenn es danach nur benannte Blöcke gibt.
Deswegen hatte ich nie die Vermutung, das ich nach einer Aktualisierung der subs den "block_01" ausführen könnte, um den Code auch zu aktualisieren. (Ich nutze immer benannte Blöcke)

Das ganze ist meiner Meinung nach nur ein Schönheitsfehler. Muss man halt wissen.  :)

2.) Das Problem, das die Funktionen subs bei mir nach einem Neustart nicht verfügbar sind, ist reproduzierbar. Die Funktionen sind erst nach dem Ausführen von "block_01" vorhanden.
Gruß
Bismosa

Zu 1. Da der subs-Block automatisch bei der Definition bzw. Änderung ausgeführt wird, sind alle Subroutinen definiert worden, deswegen gibt es auch keinen set subs-Befehl, weil es ja nichts mehr Neues zu definieren gibt.

Zu 2. Woher weißt du, dass die Subroutinen nicht definiert wurden?
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF