Dispatch und readingsBeginUpdate - Bug oder Mißbrauch meinerseits

Begonnen von olwaldi, 11 Februar 2026, 16:04:08

Vorheriges Thema - Nächstes Thema

olwaldi

Ich bastel seit einigen Tagen am Modum 70_DENON_AVR bzw. 71_DENON_ZONE - eigentlich nur, um einen Bug zu fixen, hab' aber dann doch immer mehr geändert (macht ja auch Spaß). Konkret zu meinem Problem:

Zentral in DENON_AVR ist ein riiiiiesiger if-elsif-Parser mit vielen Rücksprungpunkten für all die verschiedenen Funktionen des zu steuernden AV-Receivers. Die vielen returns habe ich "wegoptimiert", um den $return-Wert nur an einer Stelle hinter dem letzten else zurückzugeben. Es gibt eigentlich immer nur genau eine wahre Bedingung, und für die werden 2..3 Readings mittels readingsBulkUpdate gesetzt. Um nicht ständig readingsBeginUpdate/readingsEndUpdate drumherumzupacken, hat schon der originale Modul-Autor mit einem readingsBeginUpdate VOR dem if und diversen readingsEndUpdate (manchmal erst in aufgerufenen Subfunktionen) erledigt. Insbesondere das Aufbrechen von Begin/End empfand ich als unschön, hat aber funktioniert.

Nun habe ich das Modul insbesondere bzgl. readingsBegin/EndUpdate umstrukturiert und gerade bei den Hauptfunktionen (wie z.B. DENON_AVR_Read) "einfach" den gesamten Funktionsboby in ein readingsBegin/EndUpdate verpackt. Hintergedanke: Dann kann man "gedankenlos" :-) readingsBulkUpdate einfach verwenden.

Auch das funktioniert - selbst in aufgerufenen Subfunktionen bleiben Begin/End erhalten, der Code kürzer & m.E. lesbarer.

Aber, und das ist der Grund meiner Frage hier: Wird allerdings nach einem readingsBeginUpdate ein Dispatch aufgerufen, scheint das Begin "verloren" zu sein. Genauer:
readingsBeginUpdate();
readingsBulkUpdate();
...
readingsBulkUpdate();
Dispatch();
readingsBulkUpdate();
...
Das letzte readingsBulkUpdate liefert die Fehlermeldung
2026.02.11 15:00:52 1: readingsUpdate(Denon,zone2,on) missed to call readingsBeginUpdate first.
2026.02.11 15:00:52 1: stacktrace:
2026.02.11 15:00:52 1:     main::readingsBulkUpdate            called by ./FHEM/70_DENON_AVR.pm (2234)
2026.02.11 15:00:52 1:     main::DENON_AVR_Parse               called by ./FHEM/70_DENON_AVR.pm (1671)
2026.02.11 15:00:52 1:     main::DENON_AVR_Read                called by fhem.pl (4007)
2026.02.11 15:00:52 1:     main::CallFn                        called by fhem.pl (789)
Aus meiner Sicht habe ich readingsBeginUpdate "brav" aufgerufen.

Man mag jetzt grundsätzlich diskutieren, ob man wie ich mit Begin/End umgehen sollte. Aber aus den zu Anfang genannten Gründen finde ich meine Lösung gut, zumal je Begin/End nur 3..4 Readings modifiziert werden.

In Summe jedoch hat DENON_AVR extrem viele Readings (über 100), kann die aber performant anzeigen. Lediglich die Aktualisierung der fhem-GUI funktioniert nur teilweise (genauer, trotz longpoll erst nach einem Browser-Refesh). Aber das diskutiere ich schon unter https://forum.fhem.de/index.php?topic=143797.msg1357568#msg1357568


Grüßle, Michael

betateilchen

Falls Du darauf eine technisch qualifizierte Antwort erwartest, solltest Du sowas nicht in die Anfängerfragen posten. Hier liest Rudi in der Regel nicht mit.

Die Themen Dispatch() und Reaading.*Update() gehören zu fhem.pl, dafür gibt es ein passendes Unterforum.

Den Button zum Verschieben des Themas dorthin findest Du auf der Seite unten links.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

olwaldi

Hmm, ich würde das Thema ja verschieben, nur wohin genau? Und hätte ich dort überhaupt Zugriff?

Die Forumsregeln https://forum.fhem.de/index.php?topic=107904.0 geben mir eigentlich auch keinen weiteren Hinweis.

Grüßle, Michael

Beta-User

help fhem.plergibt
ZitatModule: fhem.pl Maintainer: rudolfkoenig Forum: Sonstiges

Generelle Anmerkungen:
Es ist "unschön", wenn sämtliche Probleme, die letztlich mit einer unsauberen Konstruktion eines einzelnen Moduls zusammenhängen, je isoliert diskutiert werden, ohne dass die Querbezüge klar sind.
Bezugnehmend auf die heutige Modulfassung im svn hatte ich das hier mal geschrieben:
Zitat von: Beta-User am 11 Februar 2026, 12:42:58Das betreffende Modul ist "wild":
Zitat von: olwaldi am 11 Februar 2026, 10:23:11Beim Debuggen sieht man sofort, daß viele Geräte dem Denon-Receiver notifys zuschicken, z.B. meine Lampen oder Heizung. Was wäre hier eine sinnvolle Einschränkung? Aktuell nutze ich "unreflektiert"
$hash->{NOTIFYDEV} = "global";Oder ist das schon "zu wenig"?

Grüßle, Michael


Eigentlich benötigt man für so eine Art Modul gar keine NotifyFn, sondern
a) eine AttrFn, die die dort im Moment enthaltenen Funktionen abbildet, und
b) einen durch das define ausgelösten Timer, der die ersten Infos vom Receiver holt.

Dispatch wird imo auch unnötig aufgerufen und macht vermutlich die Trigger durch Endupdate kaputt...

"Eigentlich" wäre es sinnvoll, wenn du einen Tester- oder Developer-Status anfragst, dann kannst du auch in der "Entwicklungsabteilung" schreiben.

Rudi bekommt Verschiebeaktionen übrigens häufig nicht mit, und er liest in einem anderen Thread bereits mit, der sich letztlich mit genau diesen Themen beschäftigt...

Ad Dispatch() noch: imo gehört das zu einer zweistufigen Modul-Konstruktion iSv. https://wiki.fhem.de/wiki/DevelopmentModuleIntro#Zweistufiges_Modell_f%C3%BCr_Module. Zumindest in der svn-Version scheint es aber schon keine wiki.fhem.de/wiki/DevelopmentModuleIntro#Die_Client-Liste zu geben, und es gibt auch keine ParseFn() im Modul selbst, das sich selbst als Client zu verstehen scheint...
Server: HP-elitedesk@Debian 13, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

olwaldi

Danke für die Tipps ... verschoben. Im Modulbereich für DENON_AVR stoße ich ja auch eher auf weniger Interesse - klar, dort sind die Anwender (bin ja selber eher auch einerr) unterwegs.

DENON_AVR ist ja auch gar nicht "mein" Modul - ich wollte nur einen "minibug" wegen XMLin finden und möglichst fixen (man sollte ja nicht nur Fordern:-). Und dann sieht man den nächsten Minibug usw.

Das Dispatch wird in DENON_AVR benutzt, um mit DENON_ZONE zusammenzuarbeiten. Da wollte ich eigentlich nicht genauer gucken...

Letztendlich "stört" mich aktuell nur noch, daß die Readings von DENON_AVR oft im Browser nicht aktualisiert werden. Daher stelle ich immer mal wieder Code etwas um. Gerade eben habe ich konsequent darauf verzichtet, daß DENON_AVR alle Readings immer "doppelt" gemoppelt schreibt, einmal in DENON_AVR_Set/Get, wenn eine Aktion ausgelöst wird, und zum zweiten, wenn der Receiver die Aktion in DENON_AVR_Read bestätigt. Hilft aber nicht bzgl. des nicht-automatischen Browser-Refresh.

Was mir auch noch unklar ist: Warum liest DENON_AVR_Read nur beim allerersten Mal nach einem fhem-Neustart mehrere Antworten in einem Rutsch mit 200.330bytes, ab dann (selbst bei gleicher Aktion) immer nur in Einzel-Botschaften a 10..15bytes?

Aber hier solls ja um updateBulkUpdate HINTER einem Dispatch gehen. Ich kann's durch Codeverschieben umgehen, aber vielleicht ist's ja doch ein Bug?


Grüßle, Michael

Beta-User

Zitat von: olwaldi am 12 Februar 2026, 10:59:32Das Dispatch wird in DENON_AVR benutzt, um mit DENON_ZONE zusammenzuarbeiten. Da wollte ich eigentlich nicht genauer gucken...
Ah, #1184 der svn-Version ist mir beim überblättern am Handy durchgerutscht...

Ich hatte nur - vor dem Hintergrund deiner Fragen an diversen Stellen - gesehen, dass das Modul insgesamt nicht ausgereift wirkt. Von daher finde ich es super, wenn du (optimalerweise mit dem Maintainer) da rangehst und das eine oder andere überarbeitest.

Zitat von: olwaldi am 12 Februar 2026, 10:59:32Aber hier solls ja um updateBulkUpdate HINTER einem Dispatch gehen. Ich kann's durch Codeverschieben umgehen, aber vielleicht ist's ja doch ein Bug?
Imo ist es schlicht so, dass sinnvollerweise immer nur ein einziges Device "offene" Readings im Rahmen eines bulkUpdate hat (von denen "singleUpdate" nur eine Kurzform ist!) Demnach macht es Sinn, erst das Triggern (endUpdate) auszuführen, und dann erst Dispatch() aufzurufen (das dann in der Regel ja wieder eigene Trigger im Rahmen von "bulkUpdate() auslöst).

Dass der Code - so wie er jetzt geschrieben ist - komplett unleserlich ist und eine (gefühlte) Unmenge an Doppelungen enthält und durch diese Reihung dann nicht wirklich einfacher lesbar wird, ist soweit klar.
Allerdings gibt es ziemlich sicher Wege, das zu verbessern...

PS: Das Wichtigste bei einem Modul ist erst mal, dass es im Großen und Ganzen tut, was es soll. Das ist für sich genommen ausdrücklich eine große Leistung, die ich auch nicht durch meine sehr kritische Rückmeldung im Rahmen einer sehr oberflächlichen Code-Durchsicht in irgendeiner Weise schmälern will.
Leider ist es (auch KI-unterstützt) häufig so, dass eben vorhandener funktionfähiger Code als Basis genommen wird, um erst mal überhaupt Ergebnisse zu erzielen, und das Bereinigen hinterher eher kurz kommt.

Das ist anders formuliert eher als Hilfsangebot von jemandem zu verstehen, der - ohne vorher tiefgreifende Programmiererfahrung gehabt zu haben - ein "paar" Module geerbt hat, die er eben zufällig in Benutzung hatte, und dabei entsprechende Erfahrungen gesammelt hat...
Server: HP-elitedesk@Debian 13, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

olwaldi

Danke für die Erläuterung - habe jetzt wieder immer ein readingsEndUpdate bevor Dispatch aufgerufen wird.

Grüßle, Michael