bei einem neuerlichen Anflug von Notify-Aktionen ist mir sämtliches HMCCU negativ aufgefalle.
jede Entity in HMCCU and friends lässt sich über alle Events informieren.
in CUL_HM habe ich das vor einiger Zeit unterbunden (habe es auch nur zufällig erkannt)
Bei jeder Definition einer Entity sollte
notifyRegexpChanged($defs{$name},0,1);#disable the notification
ausgeführt werden. Dann informiert der Kernal nicht mehr.
Will man tatsächlich infomiert werden betrifft das typisch nie alle Elemente. Und man will nur von dedizierten entities informiert werden. Hier wird die Entity entName über "global" und "ent2" informiert
notifyRegexpChanged($defs{entName},"global|ent2",0);
Bei HMCCU ist das extrem störend da man viele Entites hat... wirklich negativ für die Operationelle Performance
Ich habe einmal geprüft: Notifies brauchst du für global und HMCCUCHN sowie HMCCUDEV
Somit solltest du eine Funktion "updateNotifyEnrolement" erstellen in welcher du HMCCU zuweist.
sub HMCCU_enroleNotify($){
my $name = shift;
my $eList = Listjoin("|",map{$_=~s/(.*): .*/$1/;$_}grep/: HMCCU/,map{"$_: ".$defs{$_}{TYPE}}keys %defs);
$eList .= "|global";
notifyRegexpChanged($defs{$name},$eList,0);
}
und du musst das erneuern bei jedem rename/define/delete.
foreach my $event (@{$events}) {
if ($devname eq 'global') {
# Global event
if ($event eq 'INITIALIZED') {
}
elsif ($init_done) {
elsif ($event =~ /^(ATTR|DELETEATTR)/ ) {
}
elsif ($event =~ /^(RENAME|DEFINE|DELETE)/) {
HMCCU_enroleNotify($name);
}
}
Müsste ein echter Performance-Gewin für fhem werden.
Hast Du eine Doku-Seite, auf der es mehr Infos dazu gibt?
HMCCU registriert setzt ein Internal
"NOTIFYDEV global,TYPE=(HMCCU|HMCCUDEV|HMCCUCHN)"
genügt das nicht?
Die Lösung, die Martin für CUL_HM gefunden hat, ist afaik nirgends "als Muster" hinterlegt.
Vom Ergebnis her:
list TYPE=CUL_HM NOTIFYDEV
liefert genau ein Device, das als "NotifyFn-Master" agiert und alle "globalen" Events "für alle" CUL_HM-Instanzen zentral abfängt und entsprechende Aktionen auslöst (z.B. IODev etc. aktualisieren).
Was an Coding in den einzelnen Instanzen erforderlich ist, hatte Martin ja grob umrissen. Man muss dann aber folgendes sicherstellen:
- es muss zu jedem Zeitpunkt sichergestellt werden, dass weiter ein "NotifyFn-Master" existiert (=> Übergabe, wenn er selbst gelöscht wird)
- wird die letzte Entity gelöscht, muss "global" wieder generell aktiviert werden, weil sonst rereadcfg in die Hose geht (das berücksichtigt die CUL_HM-svn-Version noch nicht).
hmm, in einem anderen Beitrag von Rudolf habe ich gelesen, dass die Anzahl Devices in der Notify-Regexp auf 10 begrenzt ist.
ein
list TYPE=HMCCU NOTIFYDEV
liefert genau 1 (I/O) Device.
Würde es nicht genügen, in jeder Instanz von HMCCUDEV oder HMCCUCHN das Internal NOTIFYDEV entsprechend zu setzen?
Hmm, eine Begrenzung in NOTIFYDEV wäre mir neu, zumal ja auch devspec geht. (Das muss aber nichts heißen, wenn ich was nicht kenne).
Nach meinem Verständnis ging es Martin nicht um HMCCU (als IO-Device), sondern eher um die Clients, er nannte ausdrücklich
ZitatHMCCUCHN sowie HMCCUDEV
CUL_HM, das ich hier als Referenz genannt hatte, ist ja auch das Client-Device.
Zitat von: zap am 09 November 2021, 12:56:13
Würde es nicht genügen, in jeder Instanz von HMCCUDEV oder HMCCUCHN das Internal NOTIFYDEV entsprechend zu setzen?
Genau darum ging es m.E.. Der Vorschlag lief darauf hinaus, genau nur in (je?) einer Instanz überhaupt ein NOTIFYDEF zu setzen, _und_ in allen anderen NotifyFn() zu deaktivieren.
Also aktuell ist es so: Ich setze im I/O Device (HMCCU) NOTIFYDEV auf global,TYPE=(HMCCU|HMCCUDEV|HMCCUCHN)
Damit bekommt also das I/O Device alle Events des I/O Device (normalerweise genau 1) sowie die Events aller Client Devices vom Typ HMCCUDEV/CHN. Klar: Eigentlich braucht das I/O Device von den Client Devices nur einige wenige Events (konkret die ATTR Events).
Wenn ich es richtig verstanden habe, kann man in NOTIFYDEV nur auf einzelne Events filtern, wenn man den Devicename mit angibt. Eine Event-Filterangabe nur unter Angabe des TYPE ist nicht möglich.
Hier kommt nun notifyRegexpChanged ins Spiel, das den entsprechenden String für NOTIFYDEV erzeugt und setzt. Aber das betrifft alles nur das I/O Device, denn: In HMCCUCHN und HMCCUDEV wird keine NotifyFn verwendet.
Hmm, dann hatte ich das vermutlich falsch verstanden.
Wobei es mir andererseits jetzt beim Lesen des letzten Posts etwas unklar ist, ob nicht die Reaktion auf jeweils alle DEV/CHN nicht irgendwie im Kreis herum ist, denn das Setzen von Attributen kann man ja in den Client-Devices abfangen und an das jeweilige IO weitergeben; diesen Aspekt auf Event-Basis zu lösen finde ich nicht einleuchtend/effizient, aber das muss nichts heißen.... (und wenn, sind das "global"-Events, die nicht speziell was mit den Clients zu tun haben).
Jedenfalls ist es nach meinem Verständnis nur so, dass man NOTIFYDEV auf Device (-regex)-Basis setzt und damit nur eingrenzen kann, für welche Devices man die NotifyFn() aufgerufen haben will. Alles weitere muss man modulintern lösen.
Vielleicht mag uns ja Martin noch näher erläutern, was wir jetzt ggf. übersehen haben. (In den Modulcode werde ich jetzt jedenfalls nicht schauen, ich hatte nur was geschrieben, weil ich zwischenzeitlich die Fallstricke innerhalb CUL_HM einigermaßen kenne).
Zitat von: Beta-User am 09 November 2021, 13:56:31
diesen Aspekt auf Event-Basis zu lösen finde ich nicht einleuchtend/effizient, aber das muss nichts heißen.... (und wenn, sind das "global"-Events, die nicht speziell was mit den Clients zu tun haben).
Ja, das ist richtig. Ich denke, so werde ich es auch lösen:
- Im I/O Device nehme ich HMCCUCHN und HMCCUDEV aus NOTIFYDEV raus. Damit bekommt das I/O Device nur noch die eigenen und die globalen Events
- Die Änderung von Attributen wird in den Client-Devices (HMCCUDEV, HMCCUCHN) direkt behandelt
So dürfte die Anzahl der Notifications drastisch nach unten gehen.
CUL_HM und HMCCU sind nur eingeschränkt vergleichbar, da bei HMCCU Client-Devices von I/O Device getrennt sind (separate Module)
Ticket: https://github.com/zapccu/HMCCU/issues/137
Hi zap,
Danke für die Rückmeldung. Ein paar Dinge habe ich allerdings in deiner Antwort nicht verstanden:
Zitat von: zap am 09 November 2021, 18:24:46
Damit bekommt das I/O Device nur noch die eigenen und die globalen Events
Wieso braucht das IO-Device die eigenen Events? Die generiert es doch selbst... (Es wäre m.E. dann effizienter, die Reaktion auch direkt in der Verarbeitung der eingehenden Daten zu vercoden).
Zitat
CUL_HM und HMCCU sind nur eingeschränkt vergleichbar, da bei HMCCU Client-Devices von I/O Device getrennt sind (separate Module)
Nach meinem Verständnis ist CUL_HM "an sich" ein reines Client-Modul für die IO-Module CUL, TSCUL, HMLAN und HMUARTLGW, und damit m.E. eher mit den Modulen HMCCUDEV und HMCCUCHN vergleichbar... (Es gibt mit ACTIONDETECTOR und CCU-FHEM aber ein paar "spezielle" Varianten, die sich etwas anders verhalten als "dumme" Clients, aber das führt hier m.e. zu weit).
Aber vermutlich übersehe ich mal wieder was :) .
Muss ich nochmal im Detail durchdenken. Man muss berücksichtigen, dass mehrere IOs möglich sind, wenn jemand mehrere CCUs hat (ich zB).
Zitat von: zap am 10 November 2021, 20:22:25
Muss ich nochmal im Detail durchdenken. Man muss berücksichtigen, dass mehrere IOs möglich sind, wenn jemand mehrere CCUs hat (ich zB).
Nach meinem Verständnis dürfte es völlig gleichgültig sein, wieviele CCU's vorhanden sind, falls die erste Aktion con HMCCU nach dem Verbinden die Abfrage der darauf angelernten Devices ist: Dann müßte es reichen, in allen Clients zu checken, ob IODev (Internal und ggf. Attribut) passend gesetzt sind => Korrektur falls nicht => Fisch geputzt.
Dann noch eine RenameFn() für HMCCU, die für diesen Fall das Attribut an den Clients berichtigt und dazu dann an den Clients ein Check bei Eingabe über FHEMWEB, ob "Unsinn" eingegeben wird => die Hauptlöcher sind dicht, ohne dass man (im laufenden Betrieb) überhaupt eine NotifyFn() irgendwo braucht...
Aber vermutlich übersehe ich bei dieser einfachen Denkweise irgendwas :) .
Morgen gibt es ein Update im SVN. Damit bekommt dann das I/O Device keine Notifications mehr von den Client Devices.
Hmm, mir sind ein paar Dinge immer noch unklar (von sehr weit weg beobachtet):
- Warum handelst du das IODev-Update nicht von der Client-Seite her ab? Die Clients kennen doch ihr jeweiliges IO...
- das verbleibende "global"-Event ist "INITIALIZED" (REREADCFG fehlt. Mit Absicht?). Das könnte man durch einen InternalTimer direkt in DefFn() lösen
- Event auf HMCCU? Warum?
=> es ist an sich gar kein NotifyFn erforderlich, oder übersehe ich was?
Ich aktualisiere die Readings in den Client Devices, wenn der Nutzer bestimmte Attribute ändert. Beispiel:
Der Nutzer setzt einen Readingfilter oder ändert das Format der Readingnamen. Wenn man das Setzen der Attribute per X_Attr behandelt, ist es zu früh für ein Refresh der Readings, denn die Attribute werden erst gesetzt, wenn X_Attr undef zurückgibt.
Aber: FHEM schickt ein globales Event, wenn ein Attribut geändert wird. Und darüber löse ich dann den Refresh aus.
Und ja, HMCCU kann noch aus dem Notify Filter raus.
Zitat von: zap am 16 November 2021, 20:56:01
denn die Attribute werden erst gesetzt, wenn X_Attr undef zurückgibt.
...aber du weißt doch nach der Prüfung, was zurückgegeben wird, und alle anderen Infos sind da auch bekannt. Wenn gültig, kann also theoretisch auch direkt die passende sub aus HMCCU aufgerufen werden - man muss nur sicherstellen, dass die exisitert:
return "invalid attribute value $attrval" if !$valid;
HMCCU_subx($iohash,$name,$attrname,$attrval) if defined &HMCCU_subx;
return;
Aber auch in der jetzigen Form sollte es schon ein deutlicher Performance-Gewinn sein, Danke für's Aufgreifen der Anregungen :) .
Ich habe nur eine Funktion, die bei Änderung von Attributen die Readings refreshed. Wenn die aufgerufen wird, müssen alle Attribute schon den richtigen Zustand haben.
Die Funktion wird nur aufgerufen, wenn der Nutzer ein Attribut interaktiv anpasst, also z.B. nicht beim Start von FHEM.
Die Prüfung bei jedem einzelnen Attribut wäre ziemlich aufwändig und ineffizient.
Bisher kann ich nicht erkennen, dass sich das widersprechen würde. Du rufst doch auch schon Funktionen aus HMCCU auf, sehe ich grade (ebenfalls unter Beachtung diverser Rahmenbedingungen):
Beispiel:
https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/88_HMCCUCHN.pm#L287 => HMCCU_SetDefaultSCDatapoints
Was mir sonst bei der Gelegenheit aufgefallen ist:
- Da wir da jüngst an anderer Stelle drübergestolpert sind: #L22 => require "$attr{global}{modpath}/FHEM/88_HMCCU.pm";
https://forum.fhem.de/index.php/topic,110125.msg1183527.html#msg1183527 =>
use HMCCU;
- #L264 "$clHash->{IODev} = $defs{$attrval};" kommt mir für @startup nicht Reihenfolge-unempfindlich vor, und für nach $init_done irritiert mich der fehlende Validitätscheck.
Oo.
Danke für den Hinweis mit SetDefaultSCDatapoints. Das könnte die Ursache für einige Probleme sein.
Für require statt use hatte ich einen guten Grund, der mir gerade nicht mehr einfällt. Also probiere ich es mal wieder mit use.
...vermutlich muss es "use 88_HMCCU;" sein...
Habe aus Anlass dieses Posts (https://forum.fhem.de/index.php/topic,123686.msg1187947.html#msg1187947) von dir mal in den Code gesehen und fand einige Dinge merkwürdig, angefangen damit, dass die Initialisierungsreihenfolge der Module irgendwie "zufällig" zu sein scheint und HMCCU keine ReadyFn() hat, obwohl es ein (Netzwerk-) IO-Modul ist (siehe dazu (und zu Problemen mit "use ...") ab hier (https://forum.fhem.de/index.php/topic,123874.msg1185351.html#msg1185351) bzw. die dort verlinkten Fundstellen).
Nachdem ich mit CUL_HM&Co. (das in Teilen als Vorbild gedient zu haben scheint) jetzt einige "Erfahrungen" mit dem Initialisierungsthema sammeln "durfte": Falls Interesse besteht, können wir gerne eine Art peer review machen, um diesen Teil und evtl. weitere Kleinigkeiten zu fixen. Es scheint im Übrigen auch durchaus noch eine ganze Reihe anderer Leute zu geben, die die Module (im Unterschied zu mir) nutzen und ggf. auch bessere Perl-Kenntnisse haben wie ich (Warnung: ich höre schon den einen oder anderen rufen: "ich mach mit, aber nur, wenn das gepackaged wird". Fände ich auch sinnvoll, schon alleine wenn ich die Klimmzüge sehe, die statt "use List::Util 1.45 qw(max min uniq);" nötig sind...).
Zitat von: Beta-User am 19 November 2021, 09:49:13
Habe aus Anlass dieses Posts (https://forum.fhem.de/index.php/topic,123686.msg1187947.html#msg1187947) von dir mal in den Code gesehen und fand einige Dinge merkwürdig, angefangen damit, dass die Initialisierungsreihenfolge der Module irgendwie "zufällig" zu sein scheint und HMCCU keine ReadyFn() hat, obwohl es ein (Netzwerk-) IO-Modul ist (siehe dazu (und zu Problemen mit "use ...")
HMCCU orientiert sich (wie auch ioBroker oder OpenHab) an der Architektur der CCU. Dort gibt es (mindestens) 2 Kommunikationsebenen.
Oberste Ebene: ReGa => HMCCU
Darunter: RPC => HMCCURPCPROC (je ein Subprozess je RPC-Schnittstelle, wie.z.B.BidCos-RF, HmIP-RF, HmIP-Wired, ...)
Zu den Aufgaben der Module:
HMCCU kommuniziert mit der ReGa-Schicht der CCU: kümmert sich um das Auslesen der CCU und Geräte Konfiguration und das Senden von Befehlen an die CCU.
Die HMCCURPCPROC Subprozesse (RPC Server) empfangen die Events von der CCU (also die Statusänderungen von Geräten) und verteilen diese als Readings an die HMCCUDEV und HMCCUCHN Devices.
HMCCU und HMCCURPCPROC Subprozesse kommunizieren über TCP Sockets miteinander.
Zitat
Nachdem ich mit CUL_HM&Co. (das in Teilen als Vorbild gedient zu haben scheint)
Ganz und gar nicht. HMCCU verfolgt einen völlig anderen Ansatz. In CUL_HM werden alle Geräte individuell behandelt. HMCCU orientiert sich an Kanalrollen. Selbst neue Geräte, die gerade auf den Markt gekommen sind, können von HMCCU angesprochen werden. Ich muss dazu keinen Code anpassen. Der Nutzer muss halt einige Attribute mehr setzen, wenn eine Rolle noch nicht bekannt ist. Aber grundsätzlich funktioniert das.
In CUL_HM wurde das Rad neu erfunden, obwohl die CCU alle notwendigen Schnittstellen bereitstellt. Klar: dadurch ist man unabhängig von einer CCU, hat halt den Nachteil, dass es nicht mehr funktioniert, sobald der Hersteller (EQ-3) das Protokoll ändert / dicht macht => HmIP.
Zitat von: zap am 19 November 2021, 19:03:28
HMCCU kommuniziert mit der ReGa-Schicht der CCU: kümmert sich um das Auslesen der CCU und Geräte Konfiguration und das Senden von Befehlen an die CCU.
Die HMCCURPCPROC Subprozesse (RPC Server) empfangen die Events von der CCU (also die Statusänderungen von Geräten) und verteilen diese als Readings an die HMCCUDEV und HMCCUCHN Devices.
HMCCU und HMCCURPCPROC Subprozesse kommunizieren über TCP Sockets miteinander.
Ok, das ist nun gar nicht meine Welt.
Demnach scheinen aber die beiden Module HMCCU und HMCCURPCPROC je eine Art IO-Modul zu sein, so dass es mich halt prinzipiell wundert, dass weder ReadyFn() noch DevIo zum Einsatz kommen (also nach meinem Verständnis: die bessere Verzahnung der Module mit fhem.pl). Meine Vermutung ist, dass durch Nutzung der FHEM-Standardmethoden die teils berichteten Verbindungsprobleme insbesondere beim Start besser abgefangen werden könnten, aber das mag ja falsch sein...