Werte (alter und neuer) eines Readings vergleichen - wie geht das ?

Begonnen von Spook112, 21 Mai 2021, 18:38:59

Vorheriges Thema - Nächstes Thema

Spook112

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
Raspberry PI / RaZberry ZWAVE Modul / RFXTRX433E / 13 Fibaro FGS-222-EN-A-v1.00 / 17 VISION ZD2102-5 / 10 Somfy RTS / 4 Greenwave GWRENS310-F / Gardena Sileno City / 3 Gardena Gartensteckdosen / 2 devolo Home Control Funkschalter / 8 FIBARO System FGSD002 Smoke Sensoren

MadMax-FHEM

#1

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
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)

TomLee

Rein aus Interesse eine Frage hinterher, sind die Readings die mit der set magic-Schreibweise abgerufen werden einfach nur statisch (mit setreading) hinterlegte Werte ?

habl

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  ;)

MadMax-FHEM

#4
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
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)

Spook112

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?
Raspberry PI / RaZberry ZWAVE Modul / RFXTRX433E / 13 Fibaro FGS-222-EN-A-v1.00 / 17 VISION ZD2102-5 / 10 Somfy RTS / 4 Greenwave GWRENS310-F / Gardena Sileno City / 3 Gardena Gartensteckdosen / 2 devolo Home Control Funkschalter / 8 FIBARO System FGSD002 Smoke Sensoren

MadMax-FHEM

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
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)

Spook112

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?
Raspberry PI / RaZberry ZWAVE Modul / RFXTRX433E / 13 Fibaro FGS-222-EN-A-v1.00 / 17 VISION ZD2102-5 / 10 Somfy RTS / 4 Greenwave GWRENS310-F / Gardena Sileno City / 3 Gardena Gartensteckdosen / 2 devolo Home Control Funkschalter / 8 FIBARO System FGSD002 Smoke Sensoren

Spook112

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.
Raspberry PI / RaZberry ZWAVE Modul / RFXTRX433E / 13 Fibaro FGS-222-EN-A-v1.00 / 17 VISION ZD2102-5 / 10 Somfy RTS / 4 Greenwave GWRENS310-F / Gardena Sileno City / 3 Gardena Gartensteckdosen / 2 devolo Home Control Funkschalter / 8 FIBARO System FGSD002 Smoke Sensoren

Spook112

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 :-)
Raspberry PI / RaZberry ZWAVE Modul / RFXTRX433E / 13 Fibaro FGS-222-EN-A-v1.00 / 17 VISION ZD2102-5 / 10 Somfy RTS / 4 Greenwave GWRENS310-F / Gardena Sileno City / 3 Gardena Gartensteckdosen / 2 devolo Home Control Funkschalter / 8 FIBARO System FGSD002 Smoke Sensoren