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

Offline noansi

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1252
Antw:IODev Handling durch device
« Antwort #60 am: 06 Juni 2021, 13:51:41 »
Hallo Rudolf,

Zitat
Beim vom Benutzer ausgeloesten Schreiben der Konfiguration wird per Voreinstellung auch eine Sicherung von fhem.save erzeugt.
Ist schon veraltet. Und dabei soll dieses Backup auch nicht erstellt werden.

Zitat
fhem.save.last kann ich einbauen, allerdings sehe ich z.Zt. genausoviele neue Probleme wegen Erstellen eines weiteren Backups, wie es diese loest. Ich lass mich aber gerne umstimmen.
Es geht nur um den Fall, dass ein Modul nicht geladen werden kann. (Tippfehler des Programmierers, Tastatur mal wieder kaputt...)
Dann startet fhem durch und die Readings des Moduls sind weg. Dann hat man noch die Chance, ein Backup der Datei zu erstellen, bevor man fhem stoppt.
Mache ich derzeit dann manuell, aber manchmal vergesse ich es. Und ein älteres Backup lässt sich dann auch noch finden.
Wenn ein Modul fhem abschießt, besteht das Problem nicht, da dann die fhem.save nicht angetastet wird.

Muss nicht zwingend sein. Kann hilfreich sein. Kann auch nur per global Attribut aktivierbar sein.

Gruß, Ansgar.

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24159
Antw:IODev Handling durch device
« Antwort #61 am: 06 Juni 2021, 15:03:22 »
Zitat
Dann startet fhem durch und die Readings des Moduls sind weg. Dann hat man noch die Chance, ein Backup der Datei zu erstellen, bevor man fhem stoppt.
fhem.last ist eine Hilfe, wenn man das Problem nicht sofort merkt, aber nach dem naechsten FHEM-Restart, und man kein save vorher gemacht hat. Nach zwei Restarts ist es schon wieder zu spaet. Dafuer verursacht es Probleme, wenn die Festplatte fast voll ist.

Bin noch nicht ganz ueberzeugt, aber wenn das von Anderen auch gewuenscht wird, baue ich das ein.

Offline martinp876

  • Developer
  • Hero Member
  • ****
  • Beiträge: 10981
Antw:IODev Handling durch device
« Antwort #62 am: 06 Juni 2021, 17:21:27 »
Hallo Ansgar, Rudi,

Dokumentation per Code enthält NULL Semantik. Das ist schlicht keine Dokumentation.
"Der User kann Attribute setzen, welche nicht mehr verändert werden. ". Nun, macht man einen reboot lösche Rudi ungefragt alle Attribute, welche nun nicht mehr passen. Es ist also nur manchmal Userwille. Und das ist gut so.

Zitat
Während des FHEM Starts gibt es dabei nur das Problem, dass noch nicht alle devices definiert sind und nicht alle Attribute und noch gar keine Readings bereit stehen
CUL_HM verlässt sich schon lange nicht mehr darauf. Die Konsistenz wird NACH init_done geprüft. Nur so geht das, alles andere ist Quatch. Es ist am Modulentwickler den Init-Status zuerst zu prüfen.
Zitat
Warum dem Kernel Modifikationen des Attributwertes erlaubt sind aber dem Modul nicht ... . Ok steckt ein Nutzerwille dahinter..., war einfach umzusetzen, egal, Schwamm drüber.
Bisher hat es recht gut funktioniert, dass CUL_HM attribute angepasst hat. Ich sehe keinen Grund, das zu ändern. Es sind auch nur sehr wenige. Weiter kann der User diese typisch auch nicht ändern, da es gesperrt ist. Ich wiederhole mich.

Zitat
Ja, vier Gründe fallen mir ein, warum dies passiert.
Ich habe keinen Grund, mich auf Readings zu verlassen. Möglich, dass es klappt... da ich es nicht brauche ist es egal.

Zitat
Um sich als Programmierer diese Logik aufzuwingen,....
leute... komplizierter geht es nicht mehr? Ein Programmierer hat Verantwortung. Wenn er mist baut muss er nachbessern. Es wäre ganz einfach und braucht keinerlei weitere Attribute. Während "init" lasse tendentiell alle Attribute zu (einfache prüfungen sind möglich). Mit "Init_done" gehe einmalig über die Parameter und räume auf. Es kann so einfach sein.
User hatten anfänglich jede Menge Probleme mit der Reihenfolge in den Config files. Das ist schon jahrelang Geschichte für CUL_HM.

Und noch einmal: Bei der Eingabe wird das Attribut geprüft. Danach ist es egal? Das ist definitv ein schlechtes, inakzeptables Vorgehen. Wenn bei Eingabe geprüft wird sollte man auch weiterhin auf Kosistenz achten. Beispiele gibt es genug. Wir sind doch nicht in den 80ern und die User sind nicht ausschliesslich Hacker. Etwas service des Systems sollte schon sein.

Zitat
@Rudolf: hier wäre es ein willkommenes Feature, beim Schreiben der Readingdaten vorher automatisch ein Backup zu erzeugen
Ich will keine Backups einspielen müssen - schon garnicht von Readings - das sind leicht veränderliche Daten.

CUL_HM fährt hervorragend mit dem Umgang mit Attributen. Bisher habe ich kein einzigens konsistentes Bild oder durchgängiges Konzept gesehen oder gehört. Dass Attribute dem User gehören, nur weil es Attribute sind kann ich nicht nachvollzeihen - steht auch nirgendwo. Auch mit dem "kann nicht verändert werden" nimmt es keiner so genau. Je genauer man hinsieht desto inkonsistenter wird es.
Warum also die letzt endlich seltsame Diskussion?

Daraus folgt - zurück zum IODev:
Ist es des User's wille, ein IO festzulegen,keine Dynamik, kann schreibt er es in Attr IODev.
Entschiedet sich der User für eine Automatik setzt er ein entsprechendes Attribut (IOgrp in CUL_HM). Damit hat er seinen Willen kund getan, dem Modul das IO aus einer Liste suchen zu lassen. Damit hat er das Recht verwirkt, IODev zu setzen aus freiem Willen. Es gehört ihm nicht mehr. 

Wenn gewünscht kann man es in zig andere Parameter kopieren, ist mir egal. Den Sinn sehe ich nicht, aber wenn es sein muss...

Und für alle, welche das IO statisch definieren (warum auch immer) gilt eh das Attribut IODef.  Hier braucht es kein Reading, es ist unveränderlich und singulär.

Und zuletzt: Ich kann fhem.pl die Auswahl des IO nie und nimmer überlassen. Ich werde es IMMER selbst suchen/definieren und prüfen - auch die User-eingabe so diese erfolgt.

Somit erledigt sich die Diskussion von selbst. Ich bitte aber, die Sinnhaltigkeit der Schwemme der IODev zu überdenken. Es wäre schlicht schade, so etwas grundlos zu implementieren.

Gefällt mir Gefällt mir x 1 Liste anzeigen

Offline noansi

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1252
Antw:IODev Handling durch device
« Antwort #63 am: 06 Juni 2021, 22:26:52 »
Hallo Rudolf,

Zitat
fhem.last ist eine Hilfe, wenn man das Problem nicht sofort merkt, aber nach dem naechsten FHEM-Restart, und man kein save vorher gemacht hat. Nach zwei Restarts ist es schon wieder zu spaet. Dafuer verursacht es Probleme, wenn die Festplatte fast voll ist.

Da WriteStatefile() ein guter Punkt wäre, so was einzubauen hab ich mir den Wunsch schon mal selbst erfüllt:  ;)
  my $ofx = AttrVal('global','statefilebck',0);
  $ofx = 0 if ($ofx !~ m/^\d+$/);
  $ofx = 5 if ($ofx > 5);
  if ($ofx > 0) {
    my $bckFile = $stateFile.'.last';
    my $ofu = 5;
    do {
      unlink($bckFile.$ofu);
    } while (--$ofu >= $ofx);
    while (--$ofx) {
      rename($bckFile.$ofx, $bckFile.($ofx+1));
    }
    rename($stateFile, $bckFile.($ofx+1));
  }

Passiert so natürlich auch bei Save Config, aber der Zweck bleibt erfüllt (sonst wäre noch ein Parameter für WriteStatefile eine Möglichkeit). Und wenn ich mal schwer von Begriff bin, kann der Attributwert was höher ausfallen.

Gruß, Ansgar.

Offline martinp876

  • Developer
  • Hero Member
  • ****
  • Beiträge: 10981
Antw:IODev Handling durch device
« Antwort #64 am: 08 Juni 2021, 18:13:44 »
Ich haben einmal AssignIoPort angesehen - und verstehe die Logik nicht. Aus meiner sicht nicht Wasserdicht - wasserdicht wäre sogar einfacher.

fhem_setIoDev ist eininterner Aufruf  undmuss nicht alles prüfen, was der caller schon macht.
Der Aufruf  aus setReadings ist eigentlich sinnlos, es sollte AssignIoPort aufgerufen werden.
Eigentlich braucht man fhem_setIoDev überhaupt nicht.

In AssignIoPort wird nach Prio "proposed->attr->reading" geprüft, später noch gesucht.
1) warum hat nun proposed vorrang for Attr? Wenn es dann doch in fhem_setIoDev  geschlachtet wird?
2) warum wird nur auf das Vorhanden sein priorisiert - die Gültigkeit erst später geprüft. Wenn es dann nicht gültig ist, werden die nachrangigen nicht mehr geprüft
3) "Clients " wird nur bei der Suche betrachtet. Soll das so sein? Abwärts-Kompatiblität?

In meinem Vorschlag werden unnötige Abfragen gelöscht. Weiter werden die Priorisierungen  nur dann eingehalten, wenn diese auch nach den Vorgabengültig sind.
Die Prio von Proposed an erste Stelle zu setzen halte ich für falsch. Attr war doch nummer 1. proposed 2 und Reading 3.

Und bei der Gelegenkeit wird gleich geprüft, ob das IO auch eine WriteFn zu Verfügung stellt. Das geht evtl auch effizienter.

Was meint ihr?

sub
fhem_setIoDev($$)
{
  my ($hash, $val) = @_;

#  if(!$val || !defined($defs{$val})) { # check not required - already done by caller.
    if(!$init_done) {
      $hash->{IODevMissing} = 1;
      $hash->{IODevName} = $val;
    }
#    return "unknown IODev $val specified";
#  }
#
#  my $av = AttrVal($hash->{NAME}, "IODev", "");
#  return "$hash->{NAME}: not setting IODev to $val, as different attr exists"
#        if($av && $av ne $val);
   
  $hash->{IODev} = $defs{$val};
  setReadingsVal($hash, "IODev", $val, TimeNow()); # 120603
  delete($defs{$val}{".clientArray"}); # Force a recompute
  delete($hash->{IODevMissing});
  delete($hash->{IODevName});
  return undef;
}

sub
AssignIoPort($;$)
{
  # IO prio: 1) proposed, 2) attribut 3) reading 4) best guess
  # internalVal "Clients" required for IO.
  my ($hash, $proposed) = @_;
  my $hn = $hash->{NAME};
 
  # Set the I/O device, search for the last compatible one.
  for my $p ($proposed
            ,AttrVal($hn,     "IODev", undef)
            ,ReadingsVal($hn, "IODev", undef)
            ,sort { $defs{$b}{NR} <=> $defs{$a}{NR} }
             grep/./
            ,map{($defs{$_}{TYPE}
                  && $modules{$defs{$_}{TYPE}}
                  && $modules{$defs{$_}{TYPE}}{WriteFn}?$_:'')}
            keys %defs) {
    next if (  !$p
            || !$defs{$proposed}
            || IsDisabled($p) == 1
            || $defs{$p}{TEMPORARY}); # e.g. server clients

    my $cl = ($defs{$p}{Clients} ? $defs{$p}{Clients}
                                 : $modules{$defs{$p}{TYPE}}{Clients});
    if(   $cl
       && $defs{$p}{NAME} ne $hn
       && $cl =~ m/:$hash->{TYPE}:/) {
        fhem_setIoDev($hash, $p);
        last;
      }
    }
  }

  return if($hash->{IODev});

  if($init_done) {
    Log 3, "No I/O device found for $hn";
  } else {
    $hash->{IODevMissing} = 1;
  }
  return undef;
}

Offline noansi

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1252
Antw:IODev Handling durch device
« Antwort #65 am: 10 Juni 2021, 23:20:43 »
Hallo Martin, hallo Rudolf, hallo interessierte Mitleser,

fhem_setIoDev ist wohl bezüglich Attribut IODev Übergehen ein Torwächter und zugleich Hinweisgeber, was der User tun kann, um die verhinderte Manipulation zuzulassen. -> Attribut IODev löschen.

Zitat
1) warum hat nun proposed vorrang for Attr? Wenn es dann doch in fhem_setIoDev  geschlachtet wird?
Ich denke, weil proposed eigentlich nur dazu gedacht ist, bei neuen devices eine "Empfehlung" mitzugeben, nicht jedoch es in jedem Fall zu erzwingen.

Zitat
2) warum wird nur auf das Vorhanden sein priorisiert - die Gültigkeit erst später geprüft. Wenn es dann nicht gültig ist, werden die nachrangigen nicht mehr geprüft
Die Funktion wird bei Rudolfs Modulen am Ende der jeweiligen DefineFn aufgerufen. Damit ist zu erwarten, dass sie zwar gültig sind, aber erst nach $init_done=1 auch wirklich verfügbar sind.

Zitat
3) "Clients " wird nur bei der Suche betrachtet. Soll das so sein? Abwärts-Kompatiblität?
Systemveränderungen werden hier in der Tat nicht ausreichend berücksichtigt, insbesondere, da CUL bezüglich Clients auch mit Attribut rfmode wandelbar ist. Sich somit auch einstmals passende IODev Einstellungen zu unpassenden entwickeln können. Hier spielt es keine Rolle, ob das durch User Eingriff oder Automatik passiert.

Ich fände es auch besser, wenn bei einer ungültigen IODev Vorgabe auf was potentiell funktionsfähiges geschwenkt wird. Das ist aber Ansichtssache.

Bei gültigen Vorgabedaten ist die Aufbereitung der Suche über alle Definitionen ein Bremsschuh. In der Regel dürfte man von gültigen Vorgabedaten zu IODev ausgehen dürfen.

Gruß, Ansgar.
« Letzte Änderung: 11 Juni 2021, 20:20:30 von noansi »

Offline martinp876

  • Developer
  • Hero Member
  • ****
  • Beiträge: 10981
Antw:IODev Handling durch device
« Antwort #66 am: 12 Juni 2021, 08:37:54 »
Hallo Ansgar
mir ist schon klar, wie man "proposed" übersetzt. Das ist kein User Interface - komplett unklar, wer es wie einsetzen soll. aus meiner Sicht alles nicht durchdacht - zumindest nicht umfassend. Ich kann die Methoden verstehen, die Linie nicht.

Hallo Rudi - wie versteht sich fhem nun eigentlich? Ich dringe mit meinen Fragen bislang nicht durch und mache es hier einmal am Attr IODev und einfachen Use-cases fest.

Szenario: eine Entity ENT1 ist definiert
User-Aktion: attr ENT1 IODev IO1
fhem (das modul) prüft die Eingabe nach einem der PrüfRegeln (PR)
  PR0: nix prüfen, alles zulassen. Das Attribut wird bei Nutzung geprüft
  PR1: reject wenn IO1 nicht instanziiert ist
  PR2: reject wenn IO1 kein IO ist (impliziert PR1)
  PR3: reject wenn IO1 kein IO und der Typ von ENT1 nicht unterstützt wird (impliziert PR2)
  PR4: reject wenn IO1 disabled ist (impliziert PR1, kann mit 2 oder 3 kombiniert werden)

=> meine Wahl: PR3, min PR2
+ "Disable" ist ein (hat die Semanik eines) administrativen Attributs. Man kann "mal disablen" und "mal enablen" Daher ist es beim Attribut setzen nicht zu berücksichtigen

Haben wir uns entschieden >PR0 zu implementieren ist es nun naheliegend, den Status der Attribute immer auf Stand zu halten. Das gehört sich und zeiht sich durch das gesamte System.

Szenario: eine Entity ENT1 ist definiert, attr ENT1 IODev IO1 gesetzt, IO1 existiert
User Aktion: rename IO1 IO1new
fhem Reaktion bei ENT1
   R0: wir machen nix - was schert mich die Prüfung PR1. Hierzu passt dann nur PR0. Vielleicht wird ja alles wieder gut und der User definiert ein neues IO1. Die Hoffnung stirbt zu letzt.
   R1: rename wird rejected, da IO1 genutzt ist
   R2: attr ENT1 IODev IO1new wird ausgeführt, zumindest sinngemäß
   R3: R2 wird durchgeführt und eine Info wird nach dem Kommando ausgegeben, dass IODev implizit geändert wurde.

Meine Wahl: Da R3 nicht unterstützt wird (keine Ausgabe von Info oder Warning nach Kommando Ausführung vorgesehen) ist meine Wahl klar R2.

Szenario: eine Entity ENT1 ist definiert, attr ENT1 IODev IO1 gesetzt, IO1 existiert
User Aktion: delete IO1
fhem Reaktion bei ENT1
  R10: nix machen, still halten. Siehe R0
  R11: reject delete so lange es assoziiert ist.
  R12: delattr ENT1 IODev : Das Attribut kann nicht aufrecht erhalten werden.
  R13: R12 + eine Info ausgabe an Ende. Wie R3

Szenario: eine Entity ENT1 ist definiert, attr ENT1 IODev IO1 gesetzt, IO1 existiert, attr IO1 disable 0
User Aktion: attr IO1 disable 1
fhem Reaktion bei ENT1 und Operationelle Reaktion ( also beim senden)
  R20: nichts machen
  R21: Info ausgeben, welche Entites nun nicht mehr senden können  - oder beieinflusst sind.
  R22: deleteattr ENT1 IODev
  OR20: ENT1 kann nicht mehr senden. Das exklusiv vom User eingestellte IO ist disabled, der User hat damit das Senden unterbunden
  OR21: IO1 empfängt nichts mehr, besser: empfangene Messages werden nicht mehr geroutet.
  OR22: fhem ignoriert die User-Einstellungen und sendet über irgend ein anderes IO, wenn es gefunden wird
  OR23: Es wird nicht mehr gesendet, die messages werden gequeued
  OR24: Es wird nicht mehr gesendet, die messages werden gedropped

Ich sehe R21, min R20. R22 ist nicht sinnvoll.
OR24 ist das geradlinige Vorgehen. FHEM macht OR22 - keine Zustimmung von mir. Der User hat mit den Attributen seinen KLAREN!!! Willen eingegeben. IODev ist demnach nur ein "preferred"
Die Definition von IODev kann man interpretieren. "shall be used" lässt bei Profis keine Option zum Ausweichen, bei Normalos sicherlich schon. "which can receive data" - das ist sicher "which supports the entity type". Senden sollte schon auch gehen. Wichtiger aber: Eine CUL kann unterschiedliche Typen unterstützen - aber nicht parallel. Somit muss dies auch behandelt werden. Hier müssen wir dann noch einen Usecase erstellen.

Wie immer gilt auch ind insbesonderen für opensource: wenn wir das Verhalten nichtklar und verständlich definieren wird es der Modulentwickler nicht umsetzen können und der Anwender keine Linie erkennen.

Mein Grundsatz: Was bei der Eingabe gefordert wird muss über die gesamte Laufzeit sichergestellt werden.
Anmerkung: Probleme bei der Sequenz in der fhem-init phase muss der Modulentwickler abfangen. Prüfungen können erst an Ende durchgeführt werden.