Seite 1 von 2

3x Pause in der Rule - wie mach ich das besser

Verfasst: 22. Sep 2023 16:56
von domjo75
Hallo zusammen,

ich habe ein paar Rules, welche die Anwesenheit der Telefone der Familienmitglieder prüfen.
Das geschieht z.B. über ein ITEM, welches auf den Channel der FB horcht.
Weil der Status immer mal kippelig ist und ich nicht ständig von ON zu OFF und wieder zu ON wechseln möchte, habe ich eine simple Rule gebastelt, die 3x den Status prüft und zwischendurch immer 60sek Pause macht.

Ich bin mir sicher, dass kann man besser machen. Mit dem Threat::Sleep und den Timern hab ich es aber nicht so.
Vielleicht kann mir mal jemand etwas auf die Sprünge helfen.

So sieht das jetzt aus:

Code: Alles auswählen

// Triggers:
// - When iPhoneAmelieOnline changed

// context: iPhones-5
if( iPhoneAmelieOnline.state==OFF ) {
    Thread::sleep(60000)
    if( iPhoneAmelieOnline.state==OFF ) {
        Thread::sleep(60000)
        if( iPhoneAmelieOnline.state==OFF ) {
            Thread::sleep(60000)
            Amelies_iPhone_ATHomeFritz.postUpdate(OFF)
            // logInfo("iPhone Home Rule Fritz", "Amelies iPhone is away.")
        }
    }
} else {
    Amelies_iPhone_ATHomeFritz.postUpdate(ON)
    // logInfo("iPhone Home Rule Fritz", "Amelies iPhone is @Home.")
}

Re: 3x Pause in der Rule - wie mach ich das besser

Verfasst: 22. Sep 2023 17:56
von udo1toni
Du hast das als Script angelegt?
Sie "saubere" Variante sieht so aus: (als DSL Rule in einer .rules Datei im Verzeichnis /$OPENHAB_CONF/rules/ gespeichert, z.B. meine.rules):

Code: Alles auswählen

// globale Variablen vor der ersten Rule definieren!
var Timer   tPhoneAmelie = null

rule "Online Status Amelies iPhone"
when
    Item iPhoneAmelieOnline changed                       // Status geändert
then
    tPhoneAmelie?.cancel                                  // Timer abbrechen
    if(newState == ON) {                                  // falls neuer Status ON
        if(Amelies_iPhone_ATHomeFritz.state != ON)        // Falls nicht ON
            Amelies_iPhone_ATHomeFritz.postUpdate(ON)     // setze ON
    } else {                                              // falls neuer Status nicht ON
        tPhoneAmelie = createTimer(now.plusMinutes(3), [| // starte Timer (in drei Minuten)
            Amelies_iPhone_ATHomeFritz.postUpdate(OFF)    // setze OFF
        ])
    }
end
Die Rule triggert jedes Mal, wenn sich der Status von iPhoneAmelieOnline ändert.
Die Rule bricht zunächst einen eventuell laufenden Timer ab.
Wenn der neue Status ON ist, prüft die Rule, ob der Status des Proxy Items Amelies_iPhone_ATHomeFritz ebenfalls ON ist. Ist das nicht der Fall, setzt es den Status auf ON. (Die zusätzliche Abfrage verhindert, dass ständig unnötige Updates auf das Item erfolgen)
Ist der neue Status nicht ON, so wird ein Timer gestartet, der nach drei Minuten abläuft.
Nach Ablauf der Zeit wird das Proxy Item auf OFF gesetzt.

Sollte sich innerhalb der drei Minuten der Status ändern, so wird die Rule getriggert und bricht den laufenden Timer ab. :) Das heißt, das Item muss drei Minuten lang ununterbrochen auf dem Status OFF sein, erst dann wird die Meldung OFF weitergeleitet.

Statt also darauf zu hoffen, dass der Status zufällig nicht zweimal innerhalb der Minute wechselt (weshalb dann bei der Prüfung OFF erkannt würde), wird zuverlässig jede Änderung erkannt, mit wenig Aufwand.

Leider ist es nicht so einfach, diese Rule über die UI anzulegen, weil sie mit einer globalen Variablen arbeitet, die auch nicht so ohne weiteres ersetzbar ist.
Eine Alternative wäre ein Expiration Timer, den Du als separates Item anlegst. Wechselt das "echte" Item auf OFF, so setzt Du das Expiration Item auf ON. Wechselt das "echte" Item auf ON, so setzt Du das Expiration Item auf OFF.
Wenn die Zeit abläuft, sendet das Expiration Item den Befehl OFF, den Du nun mit einer Rule auswerten kannst, um das Proxy Item auf OFF zu setzen. Du brauchst also drei "simple" UI Rules, statt einer DSL Rule, plus ein Expiration Item statt der globalen Variablen.

Re: 3x Pause in der Rule - wie mach ich das besser

Verfasst: 22. Sep 2023 19:42
von domjo75
Hallo Udo,
Danke für die schnelle Reaktion.
Ich baue das am Wochenende mal ein und schau wie das klappt.
Meine Rules sind alle noch textbasiert. Ich finde da ist man flexibler und ich kann das im Script irgendwie auch besser überblicken
LG

Re: 3x Pause in der Rule - wie mach ich das besser

Verfasst: 22. Sep 2023 20:06
von udo1toni
domjo75 hat geschrieben: 22. Sep 2023 19:42 Meine Rules sind alle noch textbasiert.
Warum hast Du oben dann yaml angegeben?

Re: 3x Pause in der Rule - wie mach ich das besser

Verfasst: 22. Sep 2023 21:28
von domjo75
weil ich von meinem Firmenrechner nicht auf das Filesystem vom Openhabian komme.
Am Ende ist das Script aber identisch.

Re: 3x Pause in der Rule - wie mach ich das besser

Verfasst: 22. Sep 2023 21:43
von udo1toni
domjo75 hat geschrieben: 22. Sep 2023 21:28 Am Ende ist das Script aber identisch.
Das Script als solches schon, aber das Drumherum natürlich nicht :)

Re: 3x Pause in der Rule - wie mach ich das besser

Verfasst: 22. Sep 2023 23:06
von TorstenE
Ich verstehe den Timer überhaupt nicht. Wenn sich eine Person NICHT im WLAN befindet braucht auch die Fritte eine bestimmte Zeit um das zu merken. D.h. Du hast bis zu diesem Zeitpunkt sowieso schon eine Verzögerung. Mit einem Timer verschiebst Du den Zeitpunkt nur nach hinten.
Für mich gibt es nur die Situation, eine Person ist im WLAN-Umfeld oder NICHT. Wenn es "kippelig" ist, dann würde ich lieber schauen, dass das WLAN alle Bereiche sauber ausleuchtet. Denn dann muss eine Person, also das Handy wirklich sagen wir mal 50 bis 100 Meter vom Grundstück entfernt sein. Ich habe das vorher mit einer FritzBox gemacht und heute mit einem Ubiquiti Access-Point und das funktioniert richtig super.

Re: 3x Pause in der Rule - wie mach ich das besser

Verfasst: 23. Sep 2023 08:14
von domjo75
Ich habe die Erfahrung gemacht, dass die iPhone immer mal das WLAN abschalten. Eine zeitlang hatte ich nur ein Telefon in der Überwachung und an die Anwesenheit mit LOGs überwacht.
Es kam vor, dass ich auf dem Sofa gelegen habe und immer wieder LOGs bekam, dass das Telefon an und abwesend ist. Daher die Verzögerung.


@Udo: ja, das stimmt. Das Script ist Teil einer .Rule die noch mehr Regeln zur Anwesenheitsbestimmung enthält. U.a. Geofencing über den iCloud Service.
Ich packe das thematisch gern zusammen. Das hatten wir schon mal diskutiert 😜

Re: 3x Pause in der Rule - wie mach ich das besser

Verfasst: 23. Sep 2023 10:32
von udo1toni
TorstenE hat geschrieben: 22. Sep 2023 23:06 Wenn es "kippelig" ist, dann würde ich lieber schauen, dass das WLAN alle Bereiche sauber ausleuchtet.
Ja, aber nein, wie @domjo75 schon schreibt, geht es hier nicht einfach um eine Verzögerung, sondern darum, dass das OFF-Signal mindestens drei Minuten unverändert anliegen muss. iPhones wechseln in einen Sparbetrieb, wenn man sie nicht aktiv nutzt, dabei wird das WLAN abgeschaltet und nur alle paar Minuten mal kurz aktiviert, um ein "ich bin immer noch da" abzusetzen - salopp formuliert.
Da man in der FRITZ!Box nicht frei einstellen kann, wie lange ein Gerät sich nicht gemeldet haben darf, um offline erkannt zu werden, bleibt also nur, das Signal (nur von on nach off) zu verzögern.
domjo75 hat geschrieben: 23. Sep 2023 08:14Ich packe das thematisch gern zusammen. Das hatten wir schon mal diskutiert
Ja, das halte ich auch so (wobei ich nur zwei aktive .rules Dateien habe... aber auch innerhalb der Dateien sind die Rule thematisch weitgehend geordnet). Ein Grund mehr, den Timer mit globaler Variable gegenüber der UI-Variante zu bevorzugen, eine Rule (pro überwachtem Gerät).

Wenn es mehr als drei Geräte sein sollen, könnte man die Rule auch generalisieren und die Geräte alle einer Gruppe zuordnen, der Timer ist etwas komplizierter, weil wir dann eine HashMap zum Speichern der Timer Zeiger verwenden müssen, deshalb lohnt der Aufwand meiner Ansicht nach erst bei mehr als drei Geräten, auch wenn man vermutlich bereits bei zwei Geräten (unwesentlich) weniger Code braucht.

Re: 3x Pause in der Rule - wie mach ich das besser

Verfasst: 23. Sep 2023 10:58
von domjo75
Es sind nur 3 Telefone - zum Glück.. 🤭

Der Nachteil einer großen.rules ist leider, dass dir gleich alle Automatismen wegbrechen, wenn du mal nen Bock gebaut aus.
Ich hatte mal eine } vergessen und nicht im LOG geschaut. Abends ging dann keine einzige Lampe an.
Seitdem teile ich das ein bisschen auf.
Rollos, Lichter, Heizungen, Abfall, usw. sind jeweils getrennt. Es ist dann immer wieder aufs Neue spannend sich zurechtzufinden, wenn nach langer Zeit mal was nicht geht.