Autor Thema: IODev Handling durch device  (Gelesen 1368 mal)

Online noansi

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1179
IODev Handling durch device
« am: 22 April 2021, 19:16:57 »
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 wird 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.
« Letzte Änderung: 22 April 2021, 19:56:07 von noansi »

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24022
Antw:IODev Handling durch device
« Antwort #1 am: 22 April 2021, 19:59:51 »
Zitat
im 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?

Online noansi

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1179
Antw:IODev Handling durch device
« Antwort #2 am: 22 April 2021, 21:30:59 »
Hallo Rudolf,

Zitat
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.
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

Zitat
wieso 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

Zitat
Ausserhalb 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.
« Letzte Änderung: 22 April 2021, 21:42:22 von noansi »

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24022
Antw:IODev Handling durch device
« Antwort #3 am: 23 April 2021, 10:00:52 »
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?

Offline Beta-User

  • Developer
  • Hero Member
  • ****
  • Beiträge: 14353
  • "Developer"?!? Meistens doch eher "User"
Antw:IODev Handling durch device
« Antwort #4 am: 23 April 2021, 10:19:36 »
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-T620@Debian 10, 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:MySensors, Weekday-&RandomTimer, Twilight,  AttrTemplate {u.a. mqtt2, mysensors, zwave}

Online noansi

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1179
Antw:IODev Handling durch device
« Antwort #5 am: 24 April 2021, 00:06:13 »
Hallo Zusammen,

Zitat
Soweit 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.

Zitat
Attribut 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.
Zitat
das ist aber keine Begruendung es weiter zu treiben, eher im Gegenteil
Dem stimme ich zu. autosave ist bei mir übrigens aus.

Zitat
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.
Nicht die Mehrarbeit ist das Problem, sondern den Kompromiss für den Zielkonflikt zu finden.

Zitat
Bei 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.

Zitat
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)
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.
« Letzte Änderung: 24 April 2021, 12:30:04 von noansi »

Offline CoolTux

  • Developer
  • Hero Member
  • ****
  • Beiträge: 26809
Antw:IODev Handling durch device
« Antwort #6 am: 24 April 2021, 09:20:51 »
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://paypal.me/pools/c/8gULisr9BT
My FHEM Git: https://git.cooltux.net/FHEM/
Mein Dokuwiki:
https://www.cooltux.net

Offline Beta-User

  • Developer
  • Hero Member
  • ****
  • Beiträge: 14353
  • "Developer"?!? Meistens doch eher "User"
Antw:IODev Handling durch device
« Antwort #7 am: 24 April 2021, 11:35: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-T620@Debian 10, 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:MySensors, Weekday-&RandomTimer, Twilight,  AttrTemplate {u.a. mqtt2, mysensors, zwave}

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24022
Antw:IODev Handling durch device
« Antwort #8 am: 25 April 2021, 10:44:59 »
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.

Zitat
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.
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.


Zitat
Ich 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.

Online noansi

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1179
Antw:IODev Handling durch device
« Antwort #9 am: 25 April 2021, 15:54:10 »
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.
« Letzte Änderung: 25 April 2021, 16:52:01 von noansi »

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24022
Antw:IODev Handling durch device
« Antwort #10 am: 26 April 2021, 19:38:03 »
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.

Online noansi

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1179
Antw:IODev Handling durch device
« Antwort #11 am: 26 April 2021, 19:55:37 »
Hallo Rudolf,

Zitat
Habs 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.

Zitat
Das 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.

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24022
Antw:IODev Handling durch device
« Antwort #12 am: 26 April 2021, 20:22:21 »
Zitat
Weil mit $init_done üblicherweise ggf. anderer Code in Funktionen ausgeführt wird, als ohne.
Ok, aber wieso ist das ein Nachteil?

Zitat
Wenn 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.

Online noansi

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1179
Antw:IODev Handling durch device
« Antwort #13 am: 26 April 2021, 22:44:23 »
Hallo Rudolf,

Zitat
Ok, 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.

Zitat
Ich 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.

Zitat
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.
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.

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24022
Antw:IODev Handling durch device
« Antwort #14 am: 27 April 2021, 09:46:44 »
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.

Zitat
und 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.

Online noansi

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1179
Antw:IODev Handling durch device
« Antwort #15 am: 27 April 2021, 20:55:42 »
Hallo Rudolf,

Zitat
Ich fuerchte da musst Du weiter ausholen, oder an die passende Stelle verweisen, da meine Erinnerung mich im Stich gelassen hat.
Das hat gar nichts mit Dir zu tun, sondern kam im IOgrp/IODev Zusammenhang im Homematic Forum wegen unterschiedlichen Werten zwischen Reading IODev und Attribut IODev.
Wenn man das Attribut IODev nicht anbietet, darf man aus dem Code raus auch sinnvollerweise nur das Internal setzen, sonst gibt es nach einem Save Config die "Strafe" beim nächsten FHEM Start in Form von Fehlermeldungen.
Und es soll ja auch Menschen geben, die sich den diesbezüglichen fhem.pl Code noch nicht angesehen haben, die Funktionen aber dennoch benutzen wollen. ;-)

Mit dem Weglassen des Angebots des Attributs IODev habe ich auch noch ein gedankliches Problem.
Wie schon geschrieben, gibt es Szenarien für einige oder auch alle HM devices, die das Attribut IODev benötigen.
Allerdings ist das beim CUL_HM Modul erst nach der kompletten Verarbeitung der Config klar, weil erst dann alle devices,
- somit auch die optionale VCCU als IO Verwaltungsinstanz, definiert sind
und
- erst dann der jeweilige HM device Typ und Subtyp via Attribut bekannt sind. Und damit auch ein eventueller Bedarf nach Attribut IODev.
D.h. alle Nutzer, die eine Konfiguration nur auf Basis von IODev fahren, bekämen nach einem Update erst mal ihre funktionsfähige IO Konfiguration unterm Hintern weggerissen. Wenn ich es auf den ersten Blick richtig sehe auch ohne die Möglichkeit einer automatischen Umschreibung von Attribut alt auf Attribut neu auf Basis des Frameworks.
Aus Kompatibilitätsgründen ist der Weg des kompletten Weglassen des Angebots wenig empfehlenswert.

Es bliebe noch die nicht ganz saubere Möglichkeit, das Attribut für die Initilisierungphase zu zu lassen und danach für ein neues Setzen zu entziehen, um eine Umschreibung einzubauen. Danach kann AssignIoPort genutzt werden, um nur das Internal IODev zu setzen, falls beim Umschreiben kein IO zugewiesen wurde, wie ich gesehen habe.

Zitat
allerdings ist FinalizeInitFn prinzipiell auch nicht anders.
Wenn FinalizeInitFn nicht zweckgebunden definiert wird oder missbraucht wird, klar. Ein fehlendes $init_done=1 sorgt aber auch für Einschränkungen.

$init_done erst später zu setzen, z.B. wenn global INITIALIZED verarbeitet ist, würde vermutlich zu erheblichen Kompatibilitätsproblemen zu bestehenden Modulen führen.

Äquivalenz ließe sich vermutlich mit einem neuen beispielsweise global PREINITIALIZED vor INITIALIZED erreichen, wenn sich in DoTrigger und abhängigen Funktionen nicht noch ein verstecktes $init_done!=1 Problem auftut.

In's Timerhandling dafür noch eine Sonderbehandlung einzubauen fände ich deplatziert. Und kommt ohnehin erst nach dem INITIALIZED, damit auch im Ablauf nicht mehr sinnvoll.

Ich habe auch nicht generell NotifyFn und InternalTimer als Initialiserungsmöglichkeit nach dem FHEM Start kritisiert. Allerdings hast Du die finish_init() Funktion ja (rein auf das IODev Problem bezogen) auch nicht grundlos nicht via InternalTimer aufgerufen, sondern direkt im Init Ablauf, eben weil zu dem Zeitpunkt noch nichts anderes läuft, alles definiert ist und Du rechtzeitig IOs zuweisen wolltest.

Zitat
Nein, aber das ist kein Argument fuer ein Framework-Umbau, sondern eher eins fuer CUL_ReadAnswer bzw. CUL_DoInit Umbau.
Du bist nicht allein mit dem CUL Modul. Das wird auch in anderen IO-Modulen so gemacht. Ich müßte mich da mit TSCUL kompatibel auch vor dem "ersten Stein Werfer" in Deckung bringen.  ;)

Gruß, Ansgar.

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24022
Antw:IODev Handling durch device
« Antwort #16 am: 28 April 2021, 18:56:59 »
Ich habe jetzt AssignIoDev umgebaut, damit es statt Attribut ein Reading setzt, wie oben beschrieben.

Zitat
Allerdings hast Du die finish_init() Funktion ja (rein auf das IODev Problem bezogen) auch nicht grundlos nicht via InternalTimer aufgerufen, sondern direkt im Init Ablauf
Das hat damit wenig zu tun, sondern damit, dass der Aufruf ueber InternalTimer aufwendiger waere.

Ich kann (wenn immer noch gewuenscht) ein FinalizeInitFn Aufruf einbauen, bitte bestaetigen.
Am liebsten waere es mir in der aktuellen finish_init(), die macht ja bereits eine Schleife ueber alle Geraete.

Online noansi

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1179
Antw:IODev Handling durch device
« Antwort #17 am: 28 April 2021, 22:11:43 »
Hallo Rudolf,

vielen Dank für die Änderungen.
Ich schau erst mal, ob ich damit alle Probleme erschlagen kann. Ist ja doch deutlich umfangreicher geworden, als ursprünglich auch nur ansatzweise angedacht.  :)

Gruß, Ansgar.

Offline klaus.schauer

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1176
Antw:IODev Handling durch device
« Antwort #18 am: 02 Mai 2021, 13:57:51 »
Ich habe jetzt AssignIoDev umgebaut, damit es statt Attribut ein Reading setzt, wie oben beschrieben.
Das hat damit wenig zu tun, sondern damit, dass der Aufruf ueber InternalTimer aufwendiger waere.

Ich kann (wenn immer noch gewuenscht) ein FinalizeInitFn Aufruf einbauen, bitte bestaetigen.
Am liebsten waere es mir in der aktuellen finish_init(), die macht ja bereits eine Schleife ueber alle Geraete.
Ich nehme an, die Änderungen wurden in der Routine AssignIoPort vorgenommen.

Für eine Installation mit mehreren EnOcean-Transceivern ist es notwendig, statisch festzulegen, welcher dieser Transceiver als Sender verwendet wird. Diese Festlegung erfolgt nach wie vor - sowie ich das verstehe - über das Attribut IODev. Welche Routine das Attribut IODev auswertet und das Internal IODev entsprechend nachzieht, ist mir noch nicht klar.

Da das Attribut von AssignIoPort das Attribut IODev nicht mehr versorgt wird, ist diese statische Zuordnung nicht mehr gewährleistet.
Wird dies noch angepasst oder muss das Attribut IODev im EnOcean-Modul nun nach dem Aufruf von AssignIoPort beim Anlernen von Devices entsprechend beschrieben werden?

Online noansi

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1179
Antw:IODev Handling durch device
« Antwort #19 am: 02 Mai 2021, 15:03:14 »
Hallo Klaus, hallo Rudolf,

Zitat
Ich nehme an, die Änderungen wurden in der Routine AssignIoPort vorgenommen.
Nicht nur, siehe https://svn.fhem.de/trac/changeset/24351/.
CommandAttr ist zusätzlich ebenso angepasst, wie CommandSetstate.

Dabei geht es darum, die Zuweisung des IOs an das Ende des Inits zu legen (wie bisher auch), damit die IO devices auch definiert, sind, die über Attribut oder Reading beim Init gesetzt werden.

In AssignIoPort wird nur noch das Reading IODev gesetzt. Bei Save Config werden die Readings in der fhem.save gespeichert und beim nächsten Start von fhem daraus wieder gelesen.

Das Attribut IODev wird weder angetastet noch seiner Wirkung beraubt. Sprich, wird es gesetzt, dann wird das IO auch daraus eingestell (was bedeutet, dass das Internal IODev darauf eingestellt wird). Dabei wird auch das Reading IODev gleich gesetzt.
Ist das Attribut nicht gesetzt, dann wird das Reading IODev genutzt, um das IO daraus einzustellen. Also die neue Methode.
Sprich das Attribut kann dann auch gelöscht werden, ohne dass sich was an der IO Zuordnung ändert, so denn das Reading gespeichert wurde. Das Attribut wird aber nicht automatisch gelöscht.

D.h. bei autocreate wird es jetzt vermutlich interessant für Dich. Da wird nicht das IODev Attribut gesetzt, sondern nur das Reading IODev.
Wenn Du das Attribut noch unbedingt setzen möchtest, dann könntest Du es im Undefined Trigger mitgeben, so da bekannt, denke ich.

Sinnvoll ist das, wenn der Modulcode geändert wird und man beim Testen Fehler einbaut, so dass das Modul beim Start nicht mehr
geladen wird. Somit die devices nicht mehr definiert werden und damit das Reading IODev nicht gesetzt wird und somit beim nächsten FHEM Start nach Korrektur des Fehlers das Reading weg ist und eventuell ein anderes IO zugewiesen wird, wenn kein Attribut IODev in der config vorhanden ist.

Gruß, Ansgar.

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24022
Antw:IODev Handling durch device
« Antwort #20 am: 02 Mai 2021, 20:16:20 »
Wenn man im Modul auf das Vorhandensein des IODev Attributes prueft, dann kann das zu Problemen fuehren.
Ich bin der Meinung, dass das nicht notwendig ist, das Modul soll (wenn ueberhaupt!) nur das IODev Internal anfassen.
Eigentlich sollte die Kommunikation zwischen den beiden Modulen ueber IOWrite() bzw Dispatch laufen.