FHEM Forum

FHEM => Frontends => readingsGroup / readingsHistory => Thema gestartet von: Spook112 am 21 Mai 2021, 18:38:59

Titel: Werte (alter und neuer) eines Readings vergleichen - wie geht das ?
Beitrag von: Spook112 am 21 Mai 2021, 18:38:59
Hallo liebe Experten.
Ich habe einen Anwendungsfall bei dem ich partout nicht auf die richtige Lösung komme.

Was möchte ich erreichen?
Auf meiner Sonos Box gebe ich Sprachnachrichten aus wenn sich bei meinem Rasenmäher (Sileno smart) der Status ändert. Das funktioniert.
Allerdings möchte ich nicht jede mögliche Park-Meldung separat abfragen/abfangen und individuelle Meldungen ausgeben sondern beispielsweise nur eine Meldung wenn der Robi parkt - egal aus welchem Grund er parkt.
Also prüfe ich mittels eines Notify das Reading unter anderem folgendermaßen:
SILENO___Tobi:(error|ok_cutting|ok_charging|ok_searching|.*parked.*)
{if ($EVENT eq "ok_cutting") {fhem ('set Sonos_Wohnzimmer PlayURITemp [SILENO___Tobi:TobiCutting]')}
elsif ($EVENT eq "error") {fhem ('set Sonos_Wohnzimmer PlayURITemp [SILENO___Tobi:TobiError]')}
elsif ($EVENT eq "ok_charging") {fhem ('set Sonos_Wohnzimmer PlayURITemp [SILENO___Tobi:TobiCharging]')}
elsif ($EVENT eq "ok_searching") {fhem ('set Sonos_Wohnzimmer PlayURITemp [SILENO___Tobi:TobiSearching]')}
elsif ($EVENT =~ /parked/) {fhem ('set Sonos_Wohnzimmer PlayURITemp [SILENO___Tobi:TobiParked]')}
}


Nun hat Gardena eine neue Funktion eingeführt - Sensor Cut.
Wenn der Rasen kurz genug ist hört der Robi automatisch auf zu mähen - unabhängig vom Zeitplan - und parkt.
So weit so gut.
Um Mitternacht ändert die Steuerung dann automatisch den Status von "parked Sensor Cut" auf "parked Timer" - und meine Sonos Box quakt los, was ich natürlich nicht möchte.

Ich möchte also den "neuen" Wert des Readings State (parked Timer) vergleichen mit dem "alten" Wert des Readings State (parked Sensor Cut) und wenn beide Werte den Begriff "parked" enthalten keine Meldung ausgeben.

Mein Problem: Wie komme ich an den "alten" Wert des Readings ran, wenn der Trigger/das Notify erst dann anfängt zu arbeiten, wenn sich der Status geändert hat.

Ich habe schon versucht über ein UserReading zu gehen aber das hat mir auch nicht den gewünschten Erfolg gebracht, da das auch immer gleich mit dem neuen Wert überschrieben wird.

Gibt es eine Möglichkeit die Historie bzw. genau den letzten Wert aus der Historie der ReadingValues zu benutzen.

Ich hoffe ich konnte meinen Wunsch und das Problem deutlich machen.

Bin für jeden Tipp dankbar.
Gruß
Michael
Titel: Antw:Werte (alter und neuer) eines Readings vergleichen - wie geht das ?
Beitrag von: MadMax-FHEM am 21 Mai 2021, 19:19:27

attr Device oldreadings Readingname


Und dann den alten Wert mit OldReadingsVal("Device","Readingname","Ersatzwert") abfragen...

Bei dir dann verm.:


attr SILENO___Tobi oldreadings state



OldReadingsVal("SILENO___Tobi","state","n.a.")


Wobei ich jetzt nur vermute, dass der Wert in "state" steht...
...und ich auch nicht weiß, ob "hier" (oldreadings) "state" auch "besonders" behandelt wird...

Gruß, Joachim
Titel: Antw:Werte (alter und neuer) eines Readings vergleichen - wie geht das ?
Beitrag von: TomLee am 21 Mai 2021, 19:38:46
Rein aus Interesse eine Frage hinterher, sind die Readings die mit der set magic-Schreibweise abgerufen werden einfach nur statisch (mit setreading) hinterlegte Werte ?
Titel: Antw:Werte (alter und neuer) eines Readings vergleichen - wie geht das ?
Beitrag von: habl am 21 Mai 2021, 20:06:12
Reicht hier nicht einfach ein event_on_change reading:


attr SILENO___Tobi event-on-change-reading .*


oder halt nur die Readings, die von Interesse sind. Somit triggert das Notify nur bei einer Änderung eines Readings  ;)
Titel: Antw:Werte (alter und neuer) eines Readings vergleichen - wie geht das ?
Beitrag von: MadMax-FHEM am 21 Mai 2021, 20:08:56
eocr hilft hier nicht.
Hatte ich auch zunächst überlegt.

Weil: das Reading ändert sich ja!

Es ist jedesmal parking o.ä. enthalten.
Offenbar sind beide Zustände "interessant" nur halt nicht, wenn sie "hintereinander" kommen...

EDIT: eocr könnte dennoch interessant sein, wenn derselbe Wert öfter kommt! Weil sonst das mit oldreadings auch nicht geht... ;)

Gruß, Joachim
Titel: Antw:Werte (alter und neuer) eines Readings vergleichen - wie geht das ?
Beitrag von: Spook112 am 21 Mai 2021, 21:37:26
Wie Joachim schon richtig schreibt funktioniert event on change reading nicht, da sich der Status ja tatsächlich ändert.

Das mit dem Attribut Oldreadings habe ich umgesetzt. (Nur aktuell ändert sich ja nichts - da warte ich auf morgen)

Was ich noch nicht ganz verstanden habe.
Wo, an welcher Stelle soll ich das OldReadingsVal("SILENO___Tobi","state","n.a.") einsetzen?
Titel: Antw:Werte (alter und neuer) eines Readings vergleichen - wie geht das ?
Beitrag von: MadMax-FHEM am 21 Mai 2021, 22:22:14
Damit liest du den "alten Wert" aus.
Anwenden: dort wo du eben mit dem alten Wert vergleichen willst...

Also hier: elsif ($EVENT =~ /parked/) {fhem ('set Sonos_Wohnzimmer PlayURITemp [SILENO___Tobi:TobiParked]')}

Statt direkt die Sprachansage eben prüfen, ob OldreadingsVal auch \parking\ enthalten hat (und auch tatsächlich) anders war...

Gruß, Joachim
Titel: Antw:Werte (alter und neuer) eines Readings vergleichen - wie geht das ?
Beitrag von: Spook112 am 23 Mai 2021, 15:45:17
Ich habe das jetzt mal anhand der Tipps (so wie ich sie verstanden habe) umgebaut - und um besser simulieren zu können mit einer Lampenschaltung getestet.
Die Lampe kann in state zwei Zustände annehmen - on/off
Da ja die Idee war OldReadingsVal zu verwenden habe ich also folgendes "Konstrukt" gebaut.
SzHi_ZWave_SWITCH_Deckenlampe:(on|off)
{if ($EVENT eq"on") {fhem ('set Sonos_Wohnzimmer PlayURITemp [$NAME:Lampe-an]')}
elsif ($EVENT eq"off" and OldReadingsVal("$NAME","state","0") =~ /[^off]/) {fhem ('set Sonos_Wohnzimmer PlayURITemp [$NAME:Lampe-aus]')}
}

Die eine Message wird ausgegeben, wenn die Lampe angeschaltet wird, das Reading state also den Status on hat - funktioniert.
Die andere Message wird nur dann ausgegeben, wenn das Reading state den Status off hat und der alte Wert des Readings state mit OldReadingsVal abgefragt das Wort "off" nicht enthält - funktioniert auch.

Die "Umkehrprüfung" - also wenn ich die zweite Kondition ändere auf elsif ($EVENT eq"off" and OldReadingsVal("$NAME","state","0") =~ /[^on]/) {fhem ('set Sonos_Wohnzimmer PlayURITemp [$NAME:Lampe-aus]')}
}

führt auch zum gewünschten Ergebnis, nämlich dass die Message nicht ausgegeben wird.

So weit so gut.

Da in meinem Rasenmäheranwendungsfall state aber eine längere Zeichenkette enthalten kann als nur "parked" (siehe erste Nachricht in diesem Thread) wollte ich nun testen was passiert, wenn ich nur mit "Teilzeichenketten" arbeite.
Versuch =~ /[^n]/)
funktioniert. Es wird keine Message ausgegeben.
Gleicher Versuch mit =~ /[^o]/)
funktioniert aber nicht wie gewünscht und erwartet.
Die Message wird trotzdem ausgegeben, obwohl OldReadingsVal mit "on" doch das Zeichen "o" enthält.

Hat jemand eine Erklärung wo mein Denkfehler liegt?
Titel: Antw:Werte (alter und neuer) eines Readings vergleichen - wie geht das ?
Beitrag von: Spook112 am 23 Mai 2021, 16:05:00
Das war mir schon klar ;-) dass das "o" in beiden Begriffen vorkommt.
Deshalb würde ich ja erwarten, dass die Message in diesem Fall niemals ausgegeben werden dürfte.
Die Bedingung sagt ja (nach meinem Verständnis und ich bin da eben auch überhaupt kein Experte) beide Bedingungen müssen erfollt sein deswgen das "and"
Die erste ist erfüllt, denn state hat den Status "off" angenommen.
Die zweite dürfte aber nach meinem Verständnis nicht erfüllt sein, denn es soll ja kein Zeichen "o" im alten Wert von state enthalten sein.
Der ist aber immer enthalten, da sowohl in on als auch in off ein "o" enthalten ist.
Also müsste die Bedingung doch "false" zurück geben und das "and" dazu führen, dass die gesamte Bedingung "false" ist und somit nie eine Message ausgegeben werden.
Das macht natürlich eigentlich keinen Sinn - ist ja auch nur ein Test um zu schauen ob es mit "Teilzeichenketten" funktioniert.

Scheinbar nicht oder ich habe einen Denkfehler.
Bin für jeden Tipp dankbar.
Titel: Antw:Werte (alter und neuer) eines Readings vergleichen - wie geht das ?
Beitrag von: Spook112 am 05 Juni 2021, 00:40:55
Und nun, falls mal jemand vor dem selben oder einem ähnlichen Problem steht, die Lösung die funktioniert:

elsif ($EVENT =~ /parked/ and OldReadingsVal("$NAME","state","0") !~ /parked/) {fhem ('set Sonos_Wohnzimmer PlayURITemp [SILENO___Tobi:TobiParked]')}
Wenn der "neue" Status (ReadingsVal) die Zeichenfolge "parked" enthält und der vorangegangene, alte Status (OldReadingsVal) auch die Zeichenfolge "parked" enthält wird die Sprachnachricht nicht ausgegeben.
Das war das, was ich erreichen wollte.

Über einen Statuswechsel von "parked_daily_limit_reached" nach "parked_timer" möchte ich nachts um 00:04 wirklich nicht informiert werden :-)