Hallo zusammen!
Mein Wasserzähler (https://github.com/jomjol/AI-on-the-edge-device/wiki (https://github.com/jomjol/AI-on-the-edge-device/wiki)) arbeitet grundsätzlich ganz gut, aber zur Bereinigung der Werte möchte ich nur dann in die Datenbank schreiben lassen, wenn
- der Wert größer als 1 ist und
- das Reading "error" den Wert "no error" hat.
Hierzu habe ich mir ein DOIF gebastelt:
define doif_MQTT_wasser DOIF ([MQTT_wasser:value] > 1 and [MQTT_wasser:error] eq "no error") (setreading MQTT_wasser value_bereinigt {(ReadingsVal("MQTT_wasser","value",0))})
Jetzt habe ich allerdings zwei "Herausforderungen", die ich nicht alleine gelöst bekomme...
Erstens: Mein Verständnis war, dass das DOIF jedesmal loslegt, wenn sich ein neuer Wert für [MQTT_wasser:value] ergibt. Leider ist das nicht so.
Was muss ich ändern, damit das DOIF bei jedem neuen Wert für [MQTT_wasser:value] loslegt?
Zweitens: "Ab und zu" ::) wird ein neuer Wert für "MQTT_wasser value_bereinigt" errechnet - der landet dann aber nicht in der Datenbank.
Wo ist denn nur mein Denkfehler? (Natürlich habe ich an attr MQTT_wasser DbLogInclude changeabsolut_liter,value_bereinigt
gedacht...)
Danke euch allen für Hilfestellung!
Grüße!
Kornelius
Dieses DOIF kennt nur einen Zweig. Sobald dieser einmal ausgelöst ist, wird er nie wieder ausgelöst, so lange nicht entweder eine andere (hier nicht vorhandene) Bedingung erfüllt ist oder das Attribut do always gesetzt ist.
Herzlichen Dank!
(Du wirst alt wie 'ne Kuh und lernst immernoch dazu...)
Das löst zumindest die erste Herausforderung :-D
Kann das jemand nachvollziehen, dass das Reading (aus dem DOIF berechnet) nicht in die DB geschrieben wird?
Wo liegt denn hier der Fehler?
Offenbar schreibt das DOIF tatsächlich an der Datenbank vorbei.
Ich habe das DOIF nun angepasst in
defmod doif_MQTT_wasser_1 DOIF ([MQTT_wasser:value] > 1 and [MQTT_wasser:error] eq "no error") (setreading MQTT_wasser value_bereinigt1 {(ReadingsVal("MQTT_wasser","value",0))})
mit "value_bereinigt1" als Zwischenwert.
Im Device "MQTT_wasser" nutze ich nun ein userreading:
value_bereinigt {ReadingsVal("MQTT_wasser","value_bereinigt1",0)}
Und DER Wert landet nun in der DB.
:-\
Warum machst du es nicht gleich NUR als userReadings, also OHNE EXTRA DOIF?
Das ist doch total unnötig...
Und du solltest beim userReadings mit Trigger arbeiten!
Gruß, Joachim
...weil ich einfach nicht weiß, wie ich die beiden Bedingungen im userreading unterbringen müsste.
Magst du mir helfen?
Könnte das so aussehen?
value_bereinigt {if (ReadingsVal($name,"value",'')>1 and ReadingsVal($name,"error",'') eq "no error"){ReadingsVal($name,"value","")}}
Ich habe mal mit einem dummy probiert, hier zum Einfügen per Klick auf userReadings:
value_bereinigt:value.* {my $ActValue=ReadingsNum($name,"value_bereinigt",0); my $NewValue=ReadingsNum($name,"value",0); my $Error=ReadingsVal($name,"error",""); if($NewValue > 1 && $Error eq "no error"){return $NewValue}else{return $ActValue}}
Geht auch weniger ausführlich aber so evtl. verständlicher...
Ich habe ReadingsNum genommen, annehmend, dass es um eine Zahl geht, immerhin vergleichst du ja mit '<' und einer Zahl '1' ;)
EDIT: bzgl. des Triggers bin ich unsicher. Also bei meinem dummy hat es so funktioniert. Evtl. geht auch ohne .* (vermutlich sogar). Allerdings ist der Name des userReadings bei diesem Trigger nicht so gut, weil ja theoretisch (praktisch, hmmm, evtl. nicht, weil die "Event-Aktion" bereits "durch" ist) das userReadings sich selbst triggert. Evtl. einen anderen Namen überlegen, der nicht mit value anfängt...
EDIT: wobei ich mal bei mir geschaut habe und feststellen musste, dass ich die Namen auch so gewählt habe weight -> weight_cleaned (userReadings) und läuft seit einiger Zeit...
EDIT: bzgl. der Frage warum das DOIF nicht gleich geloggt wird. Hast du oder mach doch einfach mal den Eventmonitor auf und schaue, ob das DOIF auch ein Event value_bereinigt auslöst. Weil das u.U. wegen "Verhinderung einer Loop" unterbunden wird... Ansonsten habe ich auch keine Ahnung warum das nicht gleich geloggt wurde/wird...
EDIT: das sollte auch gehen
value_bereinigt:value.* {my $ActValue=ReadingsNum($name,"value_bereinigt",0); my $NewValue=ReadingsNum($name,"value",0); my $Error=ReadingsVal($name,"error",""); $NewValue > 1 && $Error eq "no error" ? return $NewValue : return $ActValue}
Gruß, Joachim
Wow. DANKE!
Ich habe es angepasst:
bereinigt:value.* {my $ActValue=ReadingsNum($name,"bereinigt",0); my $NewValue=ReadingsNum($name,"value",0); my $Error=ReadingsVal($name,"error",""); if($NewValue > 1 && $Error eq "no error"){return $NewValue}else{return $ActValue}}
Auf diese Art gibt es keine Referenz auf sich selbst.
Vielen Dank, dass du dir solch eine Mühe gemacht hast!
Zitat von: Kornelius777 am 02 November 2022, 20:03:07
Wow. DANKE!
Vielen Dank, dass du dir solch eine Mühe gemacht hast!
Klar gerne!
Viel Spaß noch, Joachim