Ermittlung von devices für NOTIFYDEV mittels notifyRegexpChanged

Begonnen von fruemmel, 12 Januar 2022, 13:07:41

Vorheriges Thema - Nächstes Thema

Beta-User

Zitat von: Damian am 20 Januar 2022, 10:05:56
Also, irgendwie widersprechen sich die Aussagen und ich finde keine verbindliche Doku zum Setzen von NOTIFYDEV:
Na ja, es gibt dann noch https://wiki.fhem.de/wiki/DevelopmentModuleAPI#notifyRegexpChanged.

Das "Grundproblem" ist aber weiter:
- Die Doku gibt den "Stand der Dinge" (halbwegs) wieder, und zwar nach dem Verständnis des jeweiligen Autors (und weder den wirklichen Ist, noch den Soll-Zustand);
- "gedacht" scheint es mal anders gewesen zu sein, als es jetzt (im wiki und von Rudi) beschrieben worden ist, teils scheinen mir auch in den Links genannte Einschränkungen (10 Devices?) nicht (mehr) zu bestehen;
- wichtiger als die Funktion zur Ermittlung des NOTIFYDEV ist imo, dass NOTIFYDEV gesetzt ist, wenn das möglich/sinnvoll ist (?). (In meinem Testsystem finde ich irritierend, was alexa da macht);
- Es ist relativ unklar (im Sinne von nicht der Doku zu entnehmen), wann es eigentlich sinnvoll ist, sich darüber Gedanken zu machen. Wer mit einem zentralen "Überwachungs-Device" viele Devices überwacht, aber intern eine gute Optimierung hat, braucht es uU. nicht, für alle anderen scheint es mir sinnvoll zu sein;
- dür Modulautoren ist die Ermittlungs-Funktion heute nur zu nutzen, wenn tatsächlich eine (nicht optimierte!) "Textkette" übergeben wird, die nichts mit devspec zu tun hat.

Von daher meine ich nach wie vor, es sei sinnvoll
- die zentrale Funktion so zu bauen, dass sie auch den typischen Anforderungen eines Moduls entspricht (insbes.: Übergabe einer devspec ermöglicht), und
- den "Kauderwelsch", den die User in der Realität halt so anliefern, im Kernbereich besser zu "übersetzen", als das derzeit der Fall ist.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Damian

Zitat von: Beta-User am 20 Januar 2022, 10:54:50
Na ja, es gibt dann noch https://wiki.fhem.de/wiki/DevelopmentModuleAPI#notifyRegexpChanged.

OK. Zum Selbersetzen von NOTIFYDEV steht da aber nichts.

Da bereits schon eine einfache Regex nur für Devicenamen scheitert

Beispiel:

defmod di_test DOIF (["bla"])

bedeutet im DOIF: bla kommt im Devicenamen vor, habe ich für solche Fälle schon meinen Filter setzen müssen: ^global$|bla, weil notifyRegexpChanged NOTIFDEV nicht setzt.

Wahrscheinlich müsste ich NOTIFYDEV auf .*bla.* direkt setzen, weil die Regex intern offenbar in ^ und $ eingepackt wird.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Beta-User

#32
Zitat von: Damian am 20 Januar 2022, 11:45:56
OK. Zum Selbersetzen von NOTIFYDEV steht da aber nichts.
Na ja, das eher allgemeine Thema ist in https://wiki.fhem.de/wiki/DevelopmentModuleIntro#X_Notify zu finden.

Zitat
Da bereits schon eine einfache Regex nur für Devicenamen scheitert
[...]
Wahrscheinlich müsste ich NOTIFYDEV auf .*bla.* direkt setzen, weil die Regex intern offenbar in ^ und $ eingepackt wird.
"Scheitern" würde ich es nicht nennen, mAn. ist die explizite Angabe dessen, was gewünscht ist vorzugswürdig (also ja: "einpacken" ala "global|.*bla.*" hilft), aber vermutlich ist das einfach eine Geschmacksfrage...

Doku wäre aber in jedem Fall gut... (EDIT: Es _ist_ durch den Verweis auf "devspec" eigentlich eindeutig, was man aber mAn. nur erkennt, wenn man weiß, wie es gemeint ist und genau den Punkt sucht...).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Beta-User

#33
Jetzt doch noch der Vorschlag für featurelevel-abhängig Code mit ein paar mehr Kommentaren und einer Umstellung in notifyRegexpCheck(), mit der dann jeweils in einer Zeile zu finden sein sollte, was zusammengehört.

# Used for debugging
sub
notifyRegexpCheck($)
{
  if ($featurelevel<6.2) {
      return
      join("\n", map {
        if($_ !~ m/^\(?([A-Za-z0-9\.\_]+(?:\.[\+\*])?)(?::.*)?\)?$/) {
          "$_: no match (ignored)"
        } elsif($defs{$1})               {
          "$_: device $1 (OK)";
        } else {
          my @ds = devspec2array($1);
          if($ds[0] ne $1) {
            "$_: devspec ".join(",",@ds)." (OK)";
          } else {
            "$_: unknown (ignored)";
          }
        }
      } split(/\|/, $_[0]));
    }

    my $re = shift // return 'No Expression to check provided!';
    my $numdef = keys %defs;
    my @fm = devspec2array($re);
    if (@fm  && $fm[0] ne $re ) {
        return "$re: matches all devices (ignored)" if $numdef == @fm;
        my $lst = join q{,}, @fm;
        return "$re: devspec for devices only - $lst (OK)";
    }
    my $consume = $re =~ s{\A\s*(\(.+\))\.\*\z}{$1}x;
    my $outer = $re =~ m{\A\s*\((.+)\)\s*\z}x; #check if outer brackets are given
    my $first = 1;
    my @list;
    while ($re) {
        (my $dev, $re) = split m{:}x, $re, 2; #get the first seperator for device/reading+rest?
        if ( $first && $outer ) {
            $first = 0;
            my $ops = $dev =~ tr/(//;
            my $clos = $dev =~ tr/)//;
            if ( $ops > $clos ) {
                chop($re);
                $dev =~ s{\A.}{}x;
            }
        }
        $dev =~ s{\A\s*\((.+)\)\s*\z}{$1}x; #remove outer brackets if given
        push @list, q{.*: matches all (ignored)} if $dev eq '.*';

        while ($dev) {
          (my $part, $dev) = notifyRegexpChangedsplitByPipe($dev);
          push @list, q{.*: matches all (ignored)} if $part eq '.*';
          if ($defs{$part}) {
              push @list, qq{$part: device $part (OK)};
          } else {
            my @ds = devspec2array($part);
            if($ds[0] ne $part) {
                my $lst = join q{,}, @ds;
                push @list, "$part: devspec $lst (OK)";
            } elsif ($numdef == @ds) {
                push @list, "$part: matches all devices (ignored)";
            } else {
                push @list, "$part: unknown (ignored)";
            }
          }
        }
        (my $other, $re) = notifyRegexpChangedsplitByPipe($re);
        $list[-1] .= "; $other: irrelevant part (OK)" if $other;
    }
    $list[-1] .= "; .*: irrelevant part (OK)" if $consume;
    return join "\n", @list;
}

sub
notifyRegexpChanged($$;$)
{
  my ($hash, $re, $disableNotifyFn) = @_;

  %ntfyHash = ();
  if($disableNotifyFn) {
    delete($hash->{NOTIFYDEV});
    $hash->{disableNotifyFn}=1;
    return;
  }
  delete($hash->{disableNotifyFn});
  if ($featurelevel<6.2) {

      my @list2 = split(/\|/, $re);
      my @list = grep { m/./ }                                     # Forum #62369
                 map  { (m/^\(?([A-Za-z0-9\.\_]+(?:\.[\+\*])?)(?::.*)?\)?$/ &&
                         ($defs{$1} || devspec2array($1) ne $1)) ? $1 : ""} @list2;
      if(@list && int(@list) == int(@list2)) {
        my %h = map { $_ => 1 } @list;
        @list = keys %h; # remove duplicates
        $hash->{NOTIFYDEV} = join(",", @list);
      } else {
        delete($hash->{NOTIFYDEV});
      }
      return; #end for featurelevels up to 6.1
  }

  my $numdef = keys %defs;
  my @fm = devspec2array($re);
  if (@fm && $fm[0] ne $re) {
    return delete $hash->{NOTIFYDEV} if $numdef == @fm; #regex was provided, matching all devices
    $hash->{NOTIFYDEV} = $re;
    return;
  }

  $re =~ s{\A\s*(\(.+\))\.\*\z}{$1}x;       # remove outer backets and closing .*
  my $first = 1;                            # we may have to treat enclosing brackets separately
  my $outer = $re =~ m{\A\s*\(.+\)\s*\z}x;  # check if outer brackets are given
  my @list;
  while ($re) {
    (my $dev, $re) = split m{:}x, $re, 2;   # get the first seperator for device/reading+rest?
    if ( $first && $outer ) {               # special treatment for outer brackets, checked by uneven number of brackes in expression that may be device/devspec
        $first = 0;
        my $ops = $dev =~ tr/(//;
        my $clos = $dev =~ tr/)//;
        if ( $ops > $clos ) {
            chop($re);                      # in case if: remove last bracket from rest
            $dev =~ s{\A.}{}x;              # in case if: remove first bracket from devspec
        }
    }
    $dev =~ s{\A\s*\((.+)\)\s*\z}{$1}x if $outer; #remove outer brackets if given
    return delete $hash->{NOTIFYDEV} if $dev eq '.*';

    while ($dev) {
      (my $part, $dev) = notifyRegexpChangedsplitByPipe($dev);
      return delete $hash->{NOTIFYDEV} if $part eq '.*';
      my @darr = devspec2array($part);
      return delete $hash->{NOTIFYDEV} if !@darr || !$defs{$part} && $darr[0] eq $part || $numdef == @darr;
      push @list, $part;
    }
    (undef, $re) = notifyRegexpChangedsplitByPipe($re); # remove irrelevant stuff like reading names and values left to next pipe at highest level, then repeat checks with remaining chars right to pipe
  }
  return delete($hash->{NOTIFYDEV}) if !@list; #we got results at all?
  my %h = map { $_ => 1 } @list;
  @list = keys %h; # remove duplicates
  $hash->{NOTIFYDEV} = join q{,}, @list;
  return;
}

sub notifyRegexpChangedsplitByPipe {
    my $string = shift // return (undef,undef);
    # split string in two pipe-separated tokens, but only in case if there is the same number of (unescaped) opening and closing brackets left to the pipe; returns tokes without pipe used for splitting
    my $lastChar = q{x}; # just something different to escape character \
    my $bracketLevel = 0;
    my $token = q{};                # start empty
    my @chars = split q{}, $string; # transform string to char array
    my $i = 0;                      # counter, needed to transform string to "" at last char of the string
    for my $char ( @chars ) {
        if ($char eq '|' && $lastChar ne '\\' && !$bracketLevel) {
            $string = substr $string, length($token) + 1;
            return ($token, $string);
        }
        $i++;
        if ($char eq q<(> && $lastChar ne '\\') {
            $bracketLevel++;
        }
        elsif ($char eq q<)> && $lastChar ne '\\') {
            $bracketLevel--;
        }
        $token .= $char;
        return ($token,'') if $i == @chars; # done, end of string, no more pipe chars
        $lastChar = $char;
    }
    return ($token, $string);
}

Edit: Code in notifyRegexpChangedsplitByPipe bei end of string leicht vereinfacht
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

rudolfkoenig

ZitatEdit: Code in notifyRegexpChangedsplitByPipe bei end of string leicht vereinfacht
Tut mir Leid fuer die Arbeit, aber diese Funktion ist mir zu Zentral, und die Aenderung zu gewaltig.


ZitatAlso, irgendwie widersprechen sich die Aussagen und ich finde keine verbindliche Doku zum Setzen von NOTIFYDEV:
Da hast Du Recht.
Nach direktes setzen von NOTIFYDEV muss man %ntfyHash leeren.
Da das in der Zukunft sich aendern kann, ist es sinnvoller notifyRegexpChanged() aufzurufen, und als Regexp die Liste aller Geraete (oder devspecs), getrennt durch |, zu uebergeben.


Ich habe fuer FileLog und notify in FHEMWEB einen Hinweis eingebaut, falls das Setzen von NOTIFYDEV nicht funktioniert hat.
Bin noch nicht ganz sicher, ob das nicht die Buechse der Pandora wird.

Beta-User

Zitat von: rudolfkoenig am 20 Januar 2022, 20:54:20
Tut mir Leid fuer die Arbeit, aber diese Funktion ist mir zu Zentral, und die Aenderung zu gewaltig.
Kein Problem, Danke für's drüber nachdenken!

Zitat
Da hast Du Recht.
Nach direktes setzen von NOTIFYDEV muss man %ntfyHash leeren.
Da das in der Zukunft sich aendern kann, ist es sinnvoller notifyRegexpChanged() aufzurufen, und als Regexp die Liste aller Geraete (oder devspecs), getrennt durch |, zu uebergeben.
Das verstehe ich soweit, habe aber weiter ein praktisches Problem. Wenn ich _oder devspecs_ so interpretiere wie in der offiziellen Doku aufgeführt (https://fhem.de/commandref_modular.html#devspec), sind auch Ausdrücke wie rC2TestDummy[12] oder TYPE=AMAD.* zulässig.

Jetzt habe ich im Testsystem mal folgene Voraussetzungen:
list devstrich0,rC2TestDummy[12],TYPE=AMAD.*
liefert:
Zitatdevstrich0
rC2TestDummy2
AMADBridge
AMADDev_A

Für das Test-notify
defmod n_test4 notify devstrich0|rC2TestDummy[12]|TYPE=AMAD.* {}
ergibt aber "das Ausrufezeichen"
ZitatCould not optimize the regexp:

    devstrich0|rC2TestDummy[12]|TYPE=AMAD.*

How I tried (notifyRegexpCheck):

    devstrich0: device devstrich0 (OK)
    rC2TestDummy[12]: no match (ignored)
    TYPE=AMAD.*: no match (ignored)
Ergo muss man "devspec" in diesem Zusammenhang anders interpretieren als woanders. Nicht glücklich, und mAn. auch nicht geeignet, Modulautoren zur Verwendung der zentralen Funktion einzuladen.

Zitat
Ich habe fuer FileLog und notify in FHEMWEB einen Hinweis eingebaut, falls das Setzen von NOTIFYDEV nicht funktioniert hat.
Bin noch nicht ganz sicher, ob das nicht die Buechse der Pandora wird.
Schauen wir mal :) .
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Damian

Etwas anderer Ansatz. Ich habe mir mal den Spaß erlaubt und habe eine Zeile vor dem notify-Aufruf in fhem.pl eingefügt:

      next if(defined($defs{$n}->{DEVREGEX}) and $dev !~ /$defs{$n}->{DEVREGEX}/);
      my $r = CallFn($n, "NotifyFn", $defs{$n}, $hash);

Wenn nun der Modul-Entwickler in seinem Modul eine reine Regex auf die zu triggernden Devices im Internal DEVREGEX setzt, dann wird er nur noch beim Treffer benachrichtigt. Der Rest merkt von diesem Filter nichts. Ggf. könnte man noch einen Syntax-Check für die Regex durchführen, falls sie gesetzt wird.

Das könnte man auch über ein Attribut realisieren.


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

rudolfkoenig

$hash->{NOTIFYDEV} zu setzen und danach  %ntfyHash zu loeschen duerfte kaum aufwendiger sein, ist dafuer effizienter, da keine Regexp-Pruefung stattfindet.

Ich habe jetzt die Funktion setNotifyDev($hash, $notifydev) hinzugefuegt, um dem Ganzen einen API Anstrich zu geben.

Damian

Zitat von: rudolfkoenig am 22 Januar 2022, 10:22:48
$hash->{NOTIFYDEV} zu setzen und danach  %ntfyHash zu loeschen duerfte kaum aufwendiger sein, ist dafuer effizienter, da keine Regexp-Pruefung stattfindet.

Ich habe jetzt die Funktion setNotifyDev($hash, $notifydev) hinzugefuegt, um dem Ganzen einen API Anstrich zu geben.

Aber ist NOTIFYDEV nicht eine kommagetrennte Liste von Device-Regex? Das ist ja was anderes als eine Regex auf alle Devices.

Im DOIF gibt der User eine reine Regex für alle Devices an. Und die möchte ich nicht auseinandernehmen. Dass sowas nicht gut funktioniert,  haben ja bereist hier gesehen.

Daher denke ich, ist NOTIFYDEV selber setzen für mich leider keine Option.

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

Damian

Ich habe mal setNotifyDev($hash, $notifydev) bei mir ausprobiert.

Bsp.

Userdefintion für einen Trigger mit der Syntax ["<Device-Regex>"]

z. B. in der Bedingung von DOIF

(["ttt1|ttt2"] or ["bla1|bla2"])

Bedeutet wenn im Device ttt1 oder ttt2  oder im Device bla1 oder bla2 vorkommt

daraus habe ich bisher folgendes aufgerufen (was oft NOTIFYDEV nicht belegte):

notifyRegexpCheck($hash, "global|.*bla1|bla2.*|.*ttt1|ttt2.*")

jetzt mit

setNotifyDev($hash, "global|.*bla1|bla2.*|.*ttt1|ttt2.*")

funktioniert schon mal.

Ich habe jetzt statt Pipe Komma als Trenner eingebaut, was wohl eher im Sinne des Erfinders ist:

setNotifyDev($hash, "global,.*bla1|bla2.*,.*ttt1|ttt2.*")

beides scheint mit gesetztem NOTIFYDEV zu funktionierten.

Damit würden einige zig-tausend DOIF-Definitionen öfters 0,002 Millisekunden weniger das System belasten :)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

naja, ich musste noch nachbessern:

mit

setNotifyDev($hash, "global,.*(bla1|bla2).*,.*(ttt1|ttt2).*")

scheint jetzt zu funktionieren.

Ich glaube, ich muss noch gut testen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

bei so etwas:

Internals:
   DEF        ([la1] or [la2])
   DOIFDEV    ^global$|^la1$|^la2$
   FUUID      61e938c0-f33f-c0d4-9330-9bb4cb117c33e731
   MODEL      FHEM
   NAME       di_test
   NOTIFYDEV  global,.*(^la1$).*,.*(^la2$).*
   NR         117
   NTFY_ORDER 50-di_test
   STATE      initialized
   TYPE       DOIF
   VERSION    25295 2021-12-04 18:13:39


sieht NOTIFYDEV irgendwie gefährlich aus, da wollen wir hoffen, dass alle Perl-Versionen damit gleichermaßen klarkommen, in DOIFDEV sieht man den internen DOIF-Filter


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

Damian

So, mein System läuft noch  :)

Alle DOIF-Devices besitzen jetzt den NOTIFYDEV-Filter, das dürfte ein paar Millisekunden einsparen.

Ich frage mich, ob es nicht besser wäre statt mit Komma die einzelnen Regex-Angaben doch mit Pipe zu trennen, es hätte die gleiche Funktionalität, allerdings solle die Abarbeitung des Arrays in fhem.pl, da nur ein Element, etwas schneller gehen, also z. B. statt:

setNotifyDev($hash,"Wasserverbrauch,Wetter,Wasserzisterne,Aussensensor,wetter_com_broich,di_Regen,Stromzaehler,global,di_zaehler,ESPEasy_Eingang_CO2,di_vaillant,Tankstelle,RKI7,CUL_WZ,outsensor")

setNotifyDev($hash,"Wasserverbrauch|Wetter|Wasserzisterne|Aussensensor|wetter_com_broich|di_Regen|Stromzaehler|global|di_zaehler|ESPEasy_Eingang_CO2|di_vaillant|Tankstelle|RKI7|CUL_WZ,outsensor")


Das sollte mit beliebigen Regex-Angaben funktionieren.

Also auch z. B.

statt
setNotifyDev($hash,"global,test,.*(bla1|bla2).*,.*(bla1).*,.*(^bla1).*")

setNotifyDev($hash,"global|test|.*(bla1|bla2).*|.*(bla1).*|.*(^bla1).*")

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

Damian

ZitatIch frage mich, ob es nicht besser wäre statt mit Komma die einzelnen Regex-Angaben doch mit Pipe zu trennen, es hätte die gleiche Funktionalität, allerdings solle die Abarbeitung des Arrays in fhem.pl, da nur ein Element, etwas schneller gehen

Ich habe mir den Code in fhem.pl nochmal angeschaut, createNtfyHash() wird ja nur einmal aufgerufen, um die Listen aufzubereiten, also hält sich der Performancegewinn in Grenzen. Daher belasse ich es beim Komma und habe dafür die Option auf andere devspecs wie z. B. FILTER.

Ich war überrascht wie viele Devices in $ntfyHash in meinem Mini-Testsystem stecken, es sind vor allem Filelogs, notify benutze ich nicht, daher kann ich keine statistischen Aussagen dazu machen, immerhin kommen DOIF-Devices jetzt selten vor :)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Beta-User

Zitat von: rudolfkoenig am 22 Januar 2022, 10:22:48
Ich habe jetzt die Funktion setNotifyDev($hash, $notifydev) hinzugefuegt, um dem Ganzen einen API Anstrich zu geben.
Interessehalber - die Handhabung von "$hash->{disableNotifyFn}" soll beim Maintainer verbleiben...?

Und wenn schon "undef" als Argument möglich sein soll, warum dann zwingend?

Und: Macht es Sinn, überhaupt einen Filter zu setzen, wenn "alle" gemeint sein sollen?

Alternativer Vorschlag (bzgl. des "ne" auch immer noch vereinfachend...):
sub
setNotifyDev($;$$)
{
  my ($hash, $ntfydev, $disableNotifyFn) = @_;
  %ntfyHash = ();
  if($ntfydev) {
    delete $hash->{disableNotifyFn};
    return $hash->{NOTIFYDEV} = $ntfydev if $ntfydev ne '.*';
    delete($hash->{NOTIFYDEV});
} else {
    delete($hash->{NOTIFYDEV});
    if (!defined $disableNotifyFn || $disableNotifyFn) {
      $hash->{disableNotifyFn}=1;
    } else {
      delete $hash->{disableNotifyFn};
    }
  }
}
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files