IODev Handling durch device

Begonnen von noansi, 22 April 2021, 19:16:57

Vorheriges Thema - Nächstes Thema

noansi

Hallo Rudolf,

ich hoffe, Du schaust hier mal rein.

Das Attribut IODev erfährt in fhem.pl in CommandAttr($$) (ab derzeit Zeile 3099) eine Sondernachbehandlung, um die Initialisierungsphase mit ungünsiger Definitionsreihenfolge "zu überstehen", so meine Codeinterpretation.

Wenn man das aber sebst handlen möchte/muss, dann stört diese Sonderbehandlung.
Ausweg ist derzeit nur, in der Attribut Funktion eine falsche Fehlermeldung zurück zu liefern, so dass Zeile 3096 mit next dafür sorgt, dass die Sonderbehandlung nicht durchgeführt wird.
    $ret = CallFn($sdev, "AttrFn", "set", $sdev, $attrName, $attrVal);
    delete($defs{$sdev}->{CL});
    if($ret) {
      push @rets, $ret;
      next;
    }

Leider wird dabei die falsche Fehlermeldung auch an den Aufrufer zurück geliefert, was unerwünscht ist. Sowohl beim FHEM Start, als auch beim händischen Setzen den Attributs.

Kannst Du damit leben, einen bestimmten Rückgabestring in der Zeile davor nicht auf das @rets array zu pushen und damit zu unterdrücken? Z.B. "IODev handled" oder "attr handled". Also so z.B.:
    $ret = CallFn($sdev, "AttrFn", "set", $sdev, $attrName, $attrVal);
    delete($defs{$sdev}->{CL});
    if($ret) {
      push @rets, $ret if ($ret ne "attr handled");
      next;
    }

Damit wird die falsche Fehlermeldung unterdrückt und das Handlen des attr Kommandos muss durch das jeweilige Modul erfolgen.

Natürlich gerne auch eine andere Alternative.

Grund ist ein Änderungsvorschlag für 10_CUL_HM.pm mit Bezug auf IODev und den Konflikten mit automatischer Zuweisung des IODev:
  elsif($attrName eq "IODev") {
    if ($cmd eq "set"){
      if ($attrVal) {
        if ($init_done) {
          return 'CUL_HM '.$name.': unknown IODev '.$attrVal.' specified'
              if (!defined($defs{$attrVal})); # noansi: resonable for a defined IO device only, real error to be reported
          $hash->{helper}{io}{restoredIO} = $attrVal; # noansi: first choice on next CUL_HM_assignIO
          CUL_HM_assignIO($hash);                     # noansi: try an assign
          delete($hash->{IODev}{'.clientArray'}) if (defined($hash->{IODev})); # Force a recompute
        }
        else {
          if (!$hash->{helper}{io}{restoredIO}) {                # noansi: do not overwrite restored data from IO, e.g. TSCUL
            $hash->{helper}{io}{restoredIO} = $attrVal;          # noansi: first choice on next CUL_HM_assignIO with vccu set till $init_done==1
            if (defined($defs{$attrVal})) {                        # noansi: resonable for a defined IO device only
              $attr{$name}{IODev}                     = $attrVal;  # noansi: first choice on next CUL_HM_assignIO with vccu not set
              @{$hash->{helper}{mRssi}{io}{$attrVal}} = (100,100); # noansi: set IO high rssi for first autoassign
              CUL_HM_assignIO($hash);                              # noansi: try an assign
              delete($hash->{IODev}{'.clientArray'}) if (defined($hash->{IODev})); # Force a recompute
            }
          }
        }
        if (defined($hash->{IODev}) && $hash->{IODev}{NAME} ne $attrVal) {
          DoTrigger('global', 'ATTR '.$name.' IODev '.$hash->{IODev}{NAME}, 1) if ($init_done);
          return 'attr handled'; # noansi: we return something to avoid fhem.pl to set $hash->{IODev} by it's own
                                 #         fhem.pl needs an adaption, not log/report it as "error"
                                 #         discussion started here https://forum.fhem.de/index.php/topic,120603.msg1151486.html#msg1151486
        }
      }
      else {
        return 'CUL_HM '.$name.': no IODev specified' if ($init_done); # noansi: real error to be reported
      }
    }
  }

Dabei stört die Nachbehandlung inklusive Setzen des Attributwertes durch CommandAttr($$).
Denn
- im CUL_HM Änderungsvorschlag wird während der FHEM Initialisierung ggf. ein notwendigerweise anderes IO bevorzugt (ein vor einem Neustart für das HM device zuständige), als der übergebene $attrval. Dann soll das IODev im device auch nicht auf den unerwünschten Wert gesetzt werden, was aber am Ende des FHEM Starts in finish_init() passiert, denn es stört im Nachgang bei der CUL_HM Nachinitialisierung.
- die für CUL_HM korrekt funktionale IO Zuweisung funktioniert nur mit CUL_HM_assignIO, weil auch dem IO das HM device als eines seiner bekannten devices mitgeteilt werden muss. Nur Setzen des Attributwertes und IODev setzen reicht nicht (betrifft auch HMLAN, HMUARTLGW). Diese Zuweisung macht CUL_HM entweder bei HM device Definition direkt nach dem FHEM Start.
- bei der vorgeschlagen Unterdrückung mittels Rückgabewert wird ein "Fehler" gelogged, der nur im Log verwirrt.
- im anderen Fall nach dem FHEM Start durch Userwunsch wird im Vorschlag bereits das IO durch CUL_HM_assignIO zugewiesen, damit auch das IO entsprechend initialisiert wird und nicht erst bei der ersten Sendenachricht an das device, wie es bisher der Fall war. Das bisherige Setzen des Attributs war (ist noch) noch nicht voll funktional.
- bei der vorgeschlagenen Unterdrückung mittels Rückgabewert wird derzeit eine störende Meldung angezeigt.


Sollte es weitere Anwendungsfälle geben, dann wäre es eventuell noch nötig, sich Gedanken um die Nachbehandlung am Ende zu machen
    addStructChange("attr", $sdev, "$sdev $attrName $attrVal")
        if(!$opt{silent} && (!defined($oVal) || $oVal ne $attrVal));
    DoTrigger("global", "ATTR $sdev $attrName $attrVal", 1) if($init_done);

die mit dem Mini Patch von oben mangels $opt{silent} Information nicht vollständig im Modul umgesetzt werden kann.

Gruß und Danke,

Ansgar.

rudolfkoenig

Zitatim CUL_HM Änderungsvorschlag wird während der FHEM Initialisierung ggf. ein notwendigerweise anderes IO bevorzugt, als der übergebene $attrval
Anders formuliert: der Benutzer setzt ein Attribut, dem Modul passt der gesetzte Wert nicht, will was Anderes setzen, und der Benutzer soll diese Manipulation nicht mitkriegen. Wenn ich dabei nichts Wesentliches uebersehen habe(*), dann finde ich das nicht ok, und bin auch nicht bereit, es mit dem Framework zu unterstuetzen.

Ausserhalb des Frameworks kann man das auch jetzt schon machen, indem man nach der Initialisierung den Attributswert ueberbuegelt.

*: Da ich keine Klartext-Begruendung fuer die Notwendigkeit gefunden habe, versuche ich das aus dem 10_CUL_HM.pm Patch abzuleiten, gelingt mir aber nicht. Wenn CUL_HM besser weiss, welches IODev zu einem Geraet gehoert, als der Benutzer, wieso laesst es das Attribut ueberhaupt zu?

noansi

#2
Hallo Rudolf,

ZitatAnders formuliert: der Benutzer setzt ein Attribut, dem Modul passt der gesetzte Wert nicht, will was Anderes setzen, und der Benutzer soll diese Manipulation nicht mitkriegen. Wenn ich dabei nichts Wesentliches uebersehen habe(*), dann finde ich das nicht ok, und bin auch nicht bereit, es mit dem Framework zu unterstuetzen.
Nun,
- der andere Wert wird für den Nutzer schon sichtbar im Attributwert. Natürlich wäre es auch kein Problem an der Stelle noch einen Log Hinweis zu ergänzen.
- mit entsprechendem verbose level gibt es auch Log Einträge, wenn IODev genutzt wird, siehe CUL_HM_assignIO Code
- nur, wenn die Möglichkeiten des automatischen IO Wechsels von CUL_HM mit VCCU genutzt werden, kommt es überhaupt zum Tragen. Und dann ist es gut, wenn nach einem FHEM Restart das zuletzt genutze IO auch wieder verwendet wird, statt des IODev Attributs. Sowohl funktional, als auch für tsculfw CULs mit wenig Speicher schonend für deren EEPROM. Wird vor einem FHEM Neustart "Save config" genutzt, dann wird auch das zuletzt zugewiesene IO im IODev Attribut in der config gespeichert.
- sofern andere IO-Typen für HM ein Rücklesen zugewiesener devices unterstützen, könnten sie den funktionalen Vorteil ebenfalls nutzen
- wenn zusätzlich noch das Attribut IOgrp mit Vorzugs-IO genutzt wird, dann ist das IODev Attribut nicht mehr "Master", sondern das gesetzte Vorzugs-IO (sofern nicht auf Fehlerstatus). Das ist schon lange so. Wenn IODev dazu nicht passend gesetzt ist, führt das derzeit eher zu Problemen.
- "unterstützen" tut es das Framework ja schon großenteils, wenn auch nicht beabsichtigt, störend ist aus bisheriger Sicht nur die u.U. verwirrende Meldung und Log Einträge

Zitatwieso laesst es das Attribut ueberhaupt zu?
Es gibt virtuelle devices, die es benötigen. Die anderen Wege greifen da nicht.
Wird keine VCCU benutzt, dann bestimmt IODev das genutzte IO. Notnagel, wenn auch das nicht verfügbar ist, ist AssignIoPort, siehe CUL_HM_assignIO Code.

Hier der Anlass, das IODev Attribut Thema überhaupt anzupacken -> https://forum.fhem.de/index.php/topic,119853.msg1144425.html#msg1144425

ZitatAusserhalb des Frameworks kann man das auch jetzt schon machen, indem man nach der Initialisierung den Attributswert ueberbuegelt.
Dann müsste das Framework das mit Kapselung verhindern, sonst verstehe ich den Einwand oben nicht so ganz in Konsequenz (nicht das ich das damit herauf beschwören wollte  ;) ).

Gruß, Ansgar.

rudolfkoenig

Soweit ich sehe, wird hier verzweifelt versucht ein Attribut fuer etwas zu missbrauchen, was eigentlich Reading sein sollte.

Attribut ist das, was der Benutzer setzt. Reading ist das, was das Modul setzt, wenn es gepsiechert werden soll. Mir ist bewusst, dass das zunehmend vermischt wird, und das ich auch nicht immer konsequent bin, das ist aber keine Begruendung es weiter zu treiben, eher im Gegenteil.

Ich verstehe schon, dass ein Umbau auf Reading mehr Arbeit bedeutet, ich faende es aber toll, wenn nicht bei jedem Problem sofort eine Ausnahme vom beabsichtigten Architektur gemacht wird.

Wie sehen das die anderen Mitschreiter?

Beta-User

Hallo zusammen,

bin zwar alles andere als ein SW-Architekt, aber ganz allgemein finde ich die Vermischung von Attribut ("gehört dem User") und "allem anderen" nicht glücklich.

Bei CUL_HM ist das Phänomen ziemlich verbreitet, eventuelle Uservorgaben auch schon mal zu "überstimmen" z.B. auch, was "model" angeht. Das "Problem" scheint mir zu sein, dass es eigentlich eine "Klasse" zwischen Readings (fhem.save) und Attributen bräuchte, die dann auch dem Userzugriff entzogen sein sollte und (klassisch) in der fhem.cfg zu verorten wäre. Das Problem ist, dass die Info vorhanden sein "muss", was schiefgeht, wenn es (noch) keine Readings gibt (ok, da kann man dann defaults setzen, die aber falsch/kontraproduktiv sein könnten) oder die fhem.save kaputt, verloren, whatever...

Jedenfalls gibt es zu dem IO-Thema auch eine Diskussion mit martinp876, in der er auch erläutert hat, was er "dann noch" im Nachgang so macht. Ist evtl. hier auch interessant: https://forum.fhem.de/index.php/topic,112302.msg1067739.html#msg1067739.
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

noansi

#5
Hallo Zusammen,

ZitatSoweit ich sehe, wird hier verzweifelt versucht ein Attribut fuer etwas zu missbrauchen, was eigentlich Reading sein sollte.
Darüber habe ich auch schon nachgedacht und denke auch, dass es eigentlich ein guter Weg wäre den Zustand auch über den Restart für alle IO Zuordnungen zu sichern. Da es bei CUL_HM_assignIO schnell gehen muss allerdings mit Sparvariante ohne Zeitstempelaktualisierung.

Zunächst ging es aber um den Fix des Problems, dass das Setzen des Attributes im laufenden Betrieb nicht zu vollwertiger Umstellung auf das gewünschte neue IO führt. Damit eine notwendige Behandlung des Attributs durch das CUL_HM Modul, um die Funktion zu erreichen. Und dabei das kleine Hinderniss der unerwünschten Meldungen.
Daraus haben sich die weiteren Fragestellungen ergeben, dass auch das Setzen beim FHEM Start bisher nicht sauber funktioniert hat.
Das vor dem Zielkonflikt, die Änderungsvorschläge nicht zu umfangreich und abweichend vom bisherigen Stand werden zu lassen. Schließlich besteht der Wunsch, dass sie vom Maintainer zumindest funktional auch übernommen werden.

Die Multi-IO Unterstützung von CUL_HM gepaart mit schnellen Antworttiminganforderung und aktiven IOs stellt etwas andere Anforderungen, als es das Framework derzeit für die IO Zurodnung bietet. Ich hoffe, das ist schon etwas klarer geworden.

Von daher sind meine Fragestellungen
- Wurde es nicht bedacht, in der vorgeschlagenen Art das Attribut allein durch das nutzende Modul behandeln zu lassen?
- Gibt es noch andere Anwendungen in FHEM bezüglich IODev, die von mehr Flexibilität bei Attribut IODev profitieren würden? Es sich somit lohnen würde meine Patchanfrage besser direkt etwas umfangreicher anzugehen, statt des vorgeschlagenen sparsamen Flickwerks?
- Würde es mal noch andere Attribute geben, die eine Sonderbehandlung in fhem.pl erfordern und die gleichfalls von der Lösung betroffen wären, respektive davon profitieren könnten?
- Habe ich eine andere Möglichkeit zur einfachen Lösung unter Nutzung von IODev übersehen, so dass mein Patchvorschlag überhaupt nicht notwendig wird?
- Habe ich Nebenwirkungen auf andere Module durch den Patchvorschlag übersehen (z.B. ist mir der Trigger am Ende erst später aufgefallen, womit Save Config anfangs kein rotes '?' bekam)?
- Oder gibt es im Gegenteil eher einen Konsens dieses spezielle Attribut durch das Framework alleine in der Sonderform verwalten zu lassen? Dann verwerfe ich den ganzen Patchvorschlag bezüglich IODev besser und suche andere Wege.

ZitatAttribut ist das, was der Benutzer setzt. Reading ist das, was das Modul setzt, wenn es gepsiechert werden soll.
Das habe ich verstanden. autosave hat die Grenzen aber aufgeweicht. Ebenso die globale Datenhaltung mit direktem Zugriff (anfangs mit wenig bis keinen Zugriffsmethoden, richtig?), die den "Missbrauch" sehr verführerisch gemacht hat, aber auch performant im Vergleich zu Methodenzugriff.
Zitatdas ist aber keine Begruendung es weiter zu treiben, eher im Gegenteil
Dem stimme ich zu. autosave ist bei mir übrigens aus.

ZitatIch verstehe schon, dass ein Umbau auf Reading mehr Arbeit bedeutet, ich faende es aber toll, wenn nicht bei jedem Problem sofort eine Ausnahme vom beabsichtigten Architektur gemacht wird.
Nicht die Mehrarbeit ist das Problem, sondern den Kompromiss für den Zielkonflikt zu finden.

ZitatBei CUL_HM ist das Phänomen ziemlich verbreitet, eventuelle Uservorgaben auch schon mal zu "überstimmen"
Ist auch durchaus sinnvoll, um historische Einstellung automatisch auf aktuellen Stand umzustellen und auch um offensichtliche Einstellfehler zu korrigieren. Macht dem User das ohnehin schon kompilzierte Einstell-Leben einfacher.

ZitatDas Problem ist, dass die Info vorhanden sein "muss", was schiefgeht, wenn es (noch) keine Readings gibt (ok, da kann man dann defaults setzen, die aber falsch/kontraproduktiv sein könnten)
Im Grunde ist das auch die Begründung für die Sonderbehandlung des IODev Attributs, da die config die Reihenfolge der Definitionen nicht vorschreibt/schreiben möchte -> Verlagerung des Setzens ans Ende der Initialisierung, wenn alle IOs definiert sein sollten.
Da kommt mein IODev Änderungsvorschlag in CUL_HM beim FHEM Init nicht dran, weshalb etwas Disziplin bei der Ordnung in der config für volle Funktionalität erforderlich ist.

Damit wäre es eigentlich besser, einem Modul die Möglichkeit zu geben, eine Funktion bereit zu stellen, die zu diesem Zeitpunkt modulspezifische IO Zuweisung durchführt.
Beispielsweise eine $modulhash->{FinalizeInitFn}, die mit Leben gefüllt werden kann, wenn es benötigt wird. Fehlt sie, werden die FHEM default Aktionen ausgeführt bzw. FHEM default Werte gesetzt. Damit auch offen für andere Problemlösungen.

Gruß, Ansgar.

CoolTux

Zitat
- Gibt es noch andere Anwendungen in FHEM bezüglich IODev, die von mehr Flexibilität bei Attribut IODev profitieren würden? Es sich somit lohnen würde meine Patchanfrage besser direkt etwas umfangreicher anzugehen, statt des vorgeschlagenen sparsamen Flickwerks?

Die Max Modulreihe würde davon profitieren. Ich weiß das Wzut daran mal gearbeitet hatte, habe aber keine Ahnung wie weit er damit gekommen ist.


Grüße
Marko
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Beta-User

Zitat von: noansi am 24 April 2021, 00:06:13
Von daher sind meine Fragestellungen
- Wurde es nicht bedacht, in der vorgeschlagenen Art das Attribut allein durch das nutzende Modul behandeln zu lassen?
Na ja, nach meiner Erfahrung in MySensors kann es zu Situationen kommen, dass einfach das falsche IO verwendet wird, wenn man sich bei autocreate etc. nicht aktiv kümmert. Weiß nicht, inwieweit das jeweils bei anderen zweistufigen Modulen bedacht wurde bzw. ob es da wegen anderer Matching-(Parse-) Strukturen dieses Problem überhaupt in der Form gab/gibt.

Spätestens dann muss der User eingreifen, ähnliches gilt, wenn er Nodes oder IO's anders platziert. Kann ich bei MySensors bei späteren Änderungen vermutlich nicht automatisiert feststellen (oder nur mit sehr hohem Aufwand), bei der initialen Festlegung ist es seit einiger Zeit gefixt.

Zitat- Oder gibt es im Gegenteil eher einen Konsens dieses spezielle Attribut durch das Framework alleine in der Sonderform verwalten zu lassen?
Aus obigen Grund: Dagegen!
gilt 1:1 auch so z.B. für MQTT2_DEVICE; da kann sich das IO auch schon mal ändern, wenn der User die zugrundeliegende Infrastruktur umbaut.

Zitat
Das habe ich verstanden. autosave hat die Grenzen aber aufgeweicht.
autosave ist mAn. zwischenzeitlich (wieder?) allgemein verpönt.

Ansonsten war das mit dem Hinweis, dass CUL_HM Attributinhalte schreibt ausdrücklich keine wirkliche Kritik! Ich fand es aus Usersicht befremdlich, aus heutiger Sicht ist es klar, dass man als Developer keine andere Option hat.
Der Kritikpunkt beschränkt sich daher lediglich auf den, dass das zugrundeliegende framework den Grundsatz "Attribute gehören dem User" durchbricht. Muss man halt an der einen oder anderen Stelle wissen und akzeptieren, that's all.
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

Ich rate weiter, da ich immer noch keine Ursachenbeschreibung gehoert habe: CUL_HM hat Probleme in Multi-Controller Setups, fuer Geraete wie Fernbedienungen, die herumgetragen werden, und deswegen jeweils von unterschiedlichen Controller angesprochen werden sollten. An sowas habe ich bei der Einfuehrung von IODev sicher nicht gedacht.

Ein Schritt zurueck:
- das IODev Internal wird in IOWrite verwendet, den "offiziellen" Weg der Kommunikation vom logischen Modul (wie CUL_HM) zu physischen (wie CUL).
- das FHEM Framework hilft mit AssignIoPort und weiteren Code, um ein passendes IODev zu finden, der Benutzer kann das mit dem IODev Attribut ueberschreiben.
- etwas ungeschickt ist, dass AssignIoPort das IODev Attribut auch setzt. Das ist notwendig wenn mehr als ein physisches Modul das Geraet theoretisch bedienen koennte, aber nur einer es richtig kann.

Attribute gehoeren dem Benutzer, die sind auch nicht dafuer ausgelegt, dauernd vom Modul geaendert zu werden, das ist die Domaene der Reading.

Vorschlag:
- AssignIoPort setzt statt den IODev Attribut ein IODev Reading
- setstate (der fuer das Setzen der Readings beim Initialisieren zustaendig ist), wird analog zu attr IODev speziell behandeln, und das IODev Reading setzen.
- wenn ein Modul IODev aendert, dann soll es auch das Reading setzen (z.Bsp. mit AssignIoPort).
- der Benutzer kann alles mit dem IODev Attribut ueberschreiben, das ist im Normalfall aber nicht notwendig.
Mir ist noch unklar, wie die Uebergangsphase funktionieren soll, stichwort Kompatibilitaet. Eine Loesung waere dem Benutzer mitzuteilen, im Problemfall bitte das alte IODev Attribut zu loeschen.

ZitatDamit wäre es eigentlich besser, einem Modul die Möglichkeit zu geben, eine Funktion bereit zu stellen, die zu diesem Zeitpunkt modulspezifische IO Zuweisung durchführt.
Ich koennte zwar ein FinalizeInitFn inbauen, aber es gibt bereits zwei Loesungen fuer dieses Problem:
- NotifyFn auf global:INITIALIZED
- im InitializeFn ein InternalTimer mit 0 als Timeout starten. Diese Variante ist deutlich billiger und einfacher als die NotifyFn Variante.


ZitatIch fand es aus Usersicht befremdlich, aus heutiger Sicht ist es klar, dass man als Developer keine andere Option hat.
Dann muss man halt an Optionen arbeiten.
Z.Bsp. indem der Modulautor im Modul- oder Instanz-Hash ein defaultAttr pflegt, was AttrVal() zurueckliefert, falls kein Attribut gesetzt ist.

noansi

#9
Hallo Zusammen,

erst mal Danke für die Beiträge bisher und Deinen Vorschlag, Rudolf.

Zusätzlich ist zu Unterscheiden zwischen FHEM Init und dem laufenden Betrieb.

Initphase:
Noch einen Schritt zurück.
Bei einem Neustart von FHEM (kann auch der harte ohne vorheriges shutdown sein) existiert eine IO Zuordnung.
Die IOs waren aktiv vorbereitet und "kennen" ihre devices auf die sie mit eigenen Automatismen antworten sollen (d.h. nicht nur sende- sondern auch empfangsrelevant) und tun dies auch weiter, wenn ihnen nichts anderes gesagt wird.
Das Attribut IODev kann zu der Zuordnung passen oder auch nicht mehr.

Die auf den IOs ist aber in der Regel die aktuell günstigere und soll möglichst beibehalten werden können. Das ist Modulabhängig und ggf. auch abhängig davon, ob das IO seinen Zuweisungszustand auch wieder zur Verfügung stellen kann.

Damit ist der attr IODev Wert in der FHEM Init Phase zu setzen oder auch anders zu setzen oder auch gar nicht. Wird es gesetzt, dann müssen alle IOs des Multi-IO-Verbundes entspechend gesetzt bzw. zurück gesetzt werden.
Ohne Ordnung in der config kann dies nur nach der kompletten Verarbeitung der config korrekt erfolgen.

Das Framework setzt derzeit sowohl das Attribut IODev, als auch das Internal IODev entweder nach Config-Attribut IODev oder entsprechend einem gefundenen kompatiblen IO.
Im Szenario ist die vom Framework gewählte Einstellung in der Regel daher falsch und die IOs nicht korrekt eingestellt, da das Framework auch diese Einstell-Funktionalität nicht bieten kann.

Bei einem harten Neustart wäre auch ein Reading IODev in der Regel falsch. Bei regulärem Neustart wäre der letzte Zustand vor einem nomalen Restart wieder nutzbar.

Zitat- NotifyFn auf global:INITIALIZED
- im InitializeFn ein InternalTimer mit 0 als Timeout starten. Diese Variante ist deutlich billiger und einfacher als die NotifyFn Variante.
- Haben beide den Nachteil, dass $init_done bereits gesetzt ist. Alle Funktionen sehen ein initialisiertes FHEM.
- Geht an/funktioniert für alle defnierten devices (so weit jeweils genutzt). Diese wiederum können einen set ausführen. Dieser set kann auf eines der devices abgesetzt werden, die eines der falsch vorbereiteten IOs nutzen, bevor deren INITIALIZED oder Init Timer durchlaufen ist.
- ReadAnswer Funktionen der IOs können bereits Empfangsdaten bekommen, die geparst und Dispatched werden und ggf. Antworten generieren, die wiederum auf die falsch vorbereiteten IOs treffen können.

Die NotifyFn Variante wird genutzt. Und leidet unter dem $init_done=1 und dass Internal IODev bereits u.U. falsch gesetzt ist. Eventuell kann man aber hier ansetzen und ein modulspezifisches init_done statt dem globalen noch nutzen.


Laufender Betrieb FHEM:
Wenn der User das Attribut IODev setzt, dann soll das Modul das Setzen des Internals IODev überschreiben und die IOs entsprechend einstellen können.
Denn wenn das Attribut IOgrp gesetzt ist und die Verwaltungsinstanz (bei CUL_HM eine VCCU) aktiv ist, dann ist automatische Zuweisung aktiv. Ggf. muss dann von der Verwaltungsinstanz ein Ausweich IO gewählt werden können. IODev habe ich für meinen Vorschlag in dem Fall nur als temporären Vorzugsvorschlag gewählt, weil damit eine Umschaltung darauf möglich ist (nicht muss) und es zu Testzwecken nützlich ist.

Das Widerspricht natürlich Deiner Vorstellung von IODev Userkontrolle.
Auf jedenfall darf das Framework nicht das Internal IODev falsch einstellen, schon gar nicht, ohne die Verbund-IOs richtig umzustellen und das ist bisher der Fall, wenn der User das Attribut im laufenden Betrieb setzt (nur das gerade aktive kann ohne Probleme gesetzt werden), denn das Attribut wird im aktuellen Modul-Code gar nicht behandelt.

Außerdem gibt es im Homematic Forum auch haufenweise User Unverständniss zur Nutzung der Attribute. Wenn IOgrp gesetzt ist und die Verwaltungsinstanz aktiv und zuständig ist, dann ist IODev nun mal nicht mehr Master bei der Zuweisung, sondern nur noch ein Notnagel.
Bei IOgrp kann man auch VorzugsIOs setzen, die bei Nutzbarkeit bevorzugt gewählt werden.
Konsequent wäre dann sogar eigentlich User setzt IODev, aber -> Attribut IOgrp VorzugsIO wird gewählt -> VCCU Attribut IOList IO wird gewählt -> Attribut IODev IO wird gewählt -> Framework AssignIO Zuweisung findet noch ein passendes IO zur Wahl, welches nutzbar ist (operabel meldet).

IOgrp alleine ist auch kein Indikator für die IODev Priorität, denn wenn die Verwaltungsinstanz nicht aktiv ist (z.B. gar nicht definiert), dann ist wieder IODev der Master und IOgrp bedeutungslos.

D.h. das Framework könnte das Internal IODev setzen, dann das Reading IODev mit Trigger und den Trigger müsste das Modul verarbeiten um die Internal Umstellung auf einen funktionalen Zustand einzustellen, wobei ihm aber gerade die Information entzogen wurde, welches IO gerade eigentlich aktiv war (und darf dabei aber nicht auf die Idee kommen CommandAttr zu nutzen um das IODev Attribut selbst zu setzen).

Gruß, Ansgar.

PS: Bezüglich Userverständnis muss ich sicherlich noch eine Prüfung auf einen geeigneten IO Typ einbauen, damit nicht irgendwas als IO gewählt wird.

rudolfkoenig

Ich bin der Ansicht, dass der Programmierer nicht immer klueger ist, als der Benutzer.
Wenn das Modul anderer Ansicht ist, dann schlage ich vor das Attribut nicht mehr anzubieten, dann muss man auch nicht gegen dem Benutzer kaempfen.
IOWrite kann man weiterhin verwenden, das Modul muss nur IODev selbst setzen.

Zitat- Haben beide den Nachteil, dass $init_done bereits gesetzt ist. Alle Funktionen sehen ein initialisiertes FHEM.
Habs noch nicht verstanden, warum das ein Nachteil ist.

Zitat- ReadAnswer Funktionen der IOs können bereits Empfangsdaten bekommen, die geparst und Dispatched werden und ggf. Antworten generieren, die wiederum auf die falsch vorbereiteten IOs treffen können.
Das gilt weder fuer die InternalTimer, noch fuer die NotifyFn Variante.

noansi

Hallo Rudolf,

ZitatHabs noch nicht verstanden, warum das ein Nachteil ist.
Weil mit $init_done üblicherweise ggf. anderer Code in Funktionen ausgeführt wird, als ohne.
Bei $init_done==0 oder undef ist klar, dass man noch im Initialiserungsbereich von FHEM unterwegs ist. Derzeit sagt es, dass noch nicht alle devices definiert und noch nicht alle Attribute und Readings gesetzt sind.

ZitatDas gilt weder fuer die InternalTimer, noch fuer die NotifyFn Variante.
Aus ReadAnswer von CUL.
$init_done ist gesetzt, wenn InternalTimer oder NotifyFn verwendet wird:
    # Dispatch data in the buffer before the proper answer.
    while(($mculdata =~ m/^([^\n]*\n)(.*)/s) || $anydata) {
      my $line = ($anydata ? $mculdata : $1);
      $mculdata = $2;
      $hash->{PARTIAL} = $mculdata; # for recursive calls
      (undef, $line) = CUL_prefix(0, $ohash, $line); # Delete prefix
      if($regexp && $line !~ m/$regexp/) {
        $line =~ s/[\n\r]+//g;
        CUL_Parse($ohash, $hash, $ohash->{NAME}, $line) if($init_done);
        $mculdata = $hash->{PARTIAL};
      } else {
        return (undef, $line);
      }
    }

Wenn die regexp nicht matched, weil schon Empfangsdaten rein kommen, dann wird geparsed, oder übersehe ich was?

Gruß, Ansgar.

rudolfkoenig

ZitatWeil mit $init_done üblicherweise ggf. anderer Code in Funktionen ausgeführt wird, als ohne.
Ok, aber wieso ist das ein Nachteil?

ZitatWenn die regexp nicht matched, weil schon Empfangsdaten rein kommen, dann wird geparsed, oder übersehe ich was?
Nein, aber das ist kein Argument fuer ein Framework-Umbau, sondern eher eins fuer CUL_ReadAnswer bzw. CUL_DoInit Umbau.
Ich gehe davon aus, dass CUL_ReadAnswer bei dem urspruenglichen Problem nur eine theoretische Rolle spielt.

noansi

Hallo Rudolf,

ZitatOk, aber wieso ist das ein Nachteil?
Weil andere Module, die ebenfalls eine NotifyFn oder InternalTimer eben schon Aktionen mit sets auslösen können. Und das bevor das CUL_HM Modul mit seiner NotifyFn dran war, um seine IOs richtig vorzubereiten. Mit Modul eigenem initDone kann man dem begegnen, die Baustelle wird nur wieder größer, weil es derzeit nicht so ist.
Daher der Vorschlag einer FinalizeInitFn, die vor $init_done=1 eingebaut werden könnte. Womit klar wäre, dass alle devices definiert, Attribute und Readings gesetzt sind, aber kein vollständiger Init auch der Module durchgelaufen ist.

ZitatIch gehe davon aus, dass CUL_ReadAnswer bei dem urspruenglichen Problem nur eine theoretische Rolle spielt.
Ein konkreter von vielen Fallstricken. Ich findes es bedenkenswert bezüglich einfach oder kompliziert auch für den Anwender des Frameworks.
Rein praktisch sehe ich beim FHEM start schon mal Log Einträge, die mir klar sagen, dass Empfangsdaten aus den IOs zu früh verarbeitet werden und Aktionen auslösen. Nicht nur im Bezug auf das ursprüngliche Problem.

ZitatIch bin der Ansicht, dass der Programmierer nicht immer klueger ist, als der Benutzer.
Wenn das Modul anderer Ansicht ist, dann schlage ich vor das Attribut nicht mehr anzubieten, dann muss man auch nicht gegen dem Benutzer kaempfen.
IOWrite kann man weiterhin verwenden, das Modul muss nur IODev selbst setzen.
Wenn der erste Satz nicht mit Bezug auf IODev flexibler im Sinne unterschiedlicher Anwendungsszenarien betrachtet werden kann, stimme ich dem zweiten zu und möchte zusätzlich nochmal präzisierend Internal IODev als zu setzend in Erinnerung rufen (weil es dazu schon mal Missverständnisse gab).

Gruß, Ansgar.

rudolfkoenig

Ich fange an deine Vorbehalte gegen InternalTimer zu verstehen, allerdings ist FinalizeInitFn prinzipiell auch nicht anders.
Wenn wir dafuer eine sinnvolle Reihenfolge erfinden koennten, dann waere das womoeglich auch fuer InternalTimer anzuwenden.

Zitatund möchte zusätzlich nochmal präzisierend Internal IODev als zu setzend in Erinnerung rufen (weil es dazu schon mal Missverständnisse gab).
Ich fuerchte da musst Du weiter ausholen, oder an die passende Stelle verweisen, da meine Erinnerung mich im Stich gelassen hat.