"Device-Variablen" in userReadings

Begonnen von lichtimc, 27 Dezember 2020, 13:29:29

Vorheriges Thema - Nächstes Thema

lichtimc

Im Perl-Modus von DOIF gibt es ja die Möglichkeit Instanzvariablen zu verwenden, welche von Trigger zu Trigger erhalten bleiben.
Im Userreading habe ich es über den Umweg "setreading" versucht aber da erscheint im Log "'setreading xxx xxx called form userReadings is prohibited".
Gibt es eine vergleichbare Möglichkeit auch für Userreadings?

MadMax-FHEM

sleep 0.1; setreading Device Readingname Wert

Aber aufpassen: NICHT auf das Reading welches wieder das userReading triggert! -> "Schleife"! Und daher natürlich einen sehr engen Trigger beim userReading!

EDIT: eben wegen solcher Schleife ist es "verboten"... Was willst du denn eigentlich tun?

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

amenomade

Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

lichtimc

#3
Ich hab einen Zisternenfüllstandssensor, den ich über HTTPMOD auslese um den Abstand zur Wasseroberfläche zu bekommen.
Leider liefert er zwischendurch mal komische Werte, also hab ich ein Reading angelegt, das den plausibelsten Wert enthält.

Ich schau nach, ob die Abweichung zum letzten Wert größer ist als 2% und wenn ja, dann gebe ich den alten Wert zurück und starte eine neue Abfrage.

Das funktioniert bereits super. Wenn sich FHEM aber mal, aus welchem Grund auch immer, aufhängt, wird das Reading nicht mehr upgedated, weil die Abweichung inzwischen oft größer als 2% ist.

Somit wollte ich eine neue Funktion einbauen: Wenn die Abweichung 10 mal hintereinander gleich groß ist, soll der Wert ins Userreading übernommen werden, obwohl er mehr als 2% abweicht.

Es scheitert am Counter, wie oft die Abweichung bereits gleich war, weil ich nicht weiß wie so ein Wert zwischen den Userreading-Events "am Leben" bleibt.

So funktionierts jedenfalls nicht:
$cwp = aktueller Wasserpegel, der gerade ausgelesen wurde,
$pwp = Plausibilisierter, aktuell gültiger Wasserpegel

Abstand_Wasserpegel_vorherigerWert {
   OldReadingsVal("Zisternenfuellstand", "Abstand_Wasserpegel_extracted", "n/v");
},
Abstand_Wasserpegel {
   my $cwp = ReadingsVal("Zisternenfuellstand", "Abstand_Wasserpegel_extracted", 0);
   my $pwp = ReadingsVal("Zisternenfuellstand", "Abstand_Wasserpegel", 0);
   my $abwcount = ReadingsVal("Zisternenfuellstand", "gleicheAbweichungAnz", 0);
   my $pcwp = ReadingsVal("Zisternenfuellstand", "letzteAbweichung", 0);
   ($cwp) = $cwp =~ /(\d+)/; #extract number
   ($pwp) = $pwp =~ /(\d+)/; #extract number
   my $diff = abs($pwp - $cwp);
   my $pct_deviation = 100 / $cwp * $diff;
   Log3 ("$name", 5, "$name: Now I have \$cwp=$cwp, \$pwp=$pwp, \$diff=$diff, \$pct_deviation=$pct_deviation");
   if ($pct_deviation > 2) {
      Log3 ("$name", 1, "$name: Abweichung mit $pct_deviation Prozent ist zu hoch. Übernehme vorherigen Wert und starte erneute Abfrage des Werts.");
      fhem("set Zisternenfuellstand reread");
      $abwcount++;
      if (not $pcwp == $cwp) {
         Log3 ("$name", 5, "$name: Abweichung unterscheidet sich von letzter Abweichung! Abweichungscounter wird zurückgesetzt!");
         $abwcount = 0;
      }
      fhem("setreading Zisternenfuellstand gleicheAbweichungAnz $abwcount");
      Log3 ("$name", 5, "$name: Gleiche Abweichung schon $abwcount mal!");
      if ($abwcount >= 10) {
         Log3 ("$name", 1, "$name: Abweichung war jetzt $abwcount mal gleich hoch. Somit nehme ich an, dass der Wert passt und übernehme ihn!");
         $abwcount = 0;
         return $cwp;
      }
      fhem("setreading Zisternenfuellstand letzteAbweichung $pcwp");
      return $pwp;
   }
   return $cwp;
}


Ich versuch jetzt mal ein "sleep" davor...
sleep 0.1 vor dem setreading bringt nichts, da erscheint trotzdem die prohibited-Meldung im Log.

Damian

Im DOIF gibt es für Ausreißer eine Funktion, z. B.:

[Zisternenfuellstand:Abstand_Wasserpegel_extracted:med5]

siehe: https://fhem.de/commandref_DE.html#DOIF_Reading_Funktionen
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

lichtimc

Danke, übers DOIF wäre das sowieso kein Problem, ich würde es aber gerne direkt im Userreading lösen, damit ich nicht noch ein Device brauche.
Gibts dafür auch eine Möglichkeit?

MadMax-FHEM

Wie geschrieben sehe ich keinen Trigger beim userReadings.

Ob damit das "prohibited" weg geht weiß ich nicht.

Auslagern des userReadings-Codes in eine myUtils und dort mit globaler Variable?

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)