Wieso funktioniert mein Timer nicht?

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Benutzeravatar
udo1toni
Beiträge: 15249
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Wieso funktioniert mein Timer nicht?

Beitrag von udo1toni »

Im Grunde reicht hier ein Timer. Das Ganze ist eine kleine StateMachine.

Code: Alles auswählen

var Timer tFlur_SICHERHEIT = null                                                            // Timervariable fuer SICHERHEIT Flur
vat Integer nStep = 0

rule "SICHERHEIT Flur_2 Licht_AUS"
when
    Item Flur2_Power changed to ON                                                           // Wenn Flur_2 AN-geschaltet wurde
then
    logInfo("flur","--- SICHERHEIT--Flur_2 wurde EIN-geschaltet ---")
    tFlur_SICHERHEIT?.cancel()                                                               // Timer entfernen, falls vorhanden
    nStep = 0
    logInfo("flur","--- SICHERHEIT--Flur_1 Gedenksekunde für 5 sec gesetzt ---")
    tFlur_SICHERHEIT = createTimer(now.plusSeconds(5), [|                                    // Timer auf 5 sec anlegen
        nStep = nStep + 1
        if(nStep == 1 && Flur1_Power.state == OFF) {                                         // wenn Flur_1 AUS
            logInfo("flur","--- SICHERHEIT--Flur_1 ist AUS-geschaltet Timer auf 35 sec ---")
            tFlur_SICHERHEIT.reschedule(now.plusSeconds(35))                                 // Timer auf 35 sec anlegen
        } else if(nStep == 1 && Flur1_Power.state == ON) {
            logInfo("flur","--- SICHERHEIT--Flur_1 ist AN-geschaltet Timer nicht gestartet ---")
        } else if(nStep == 2 && Flur2_Power.state == ON) {
            Flur2_Power.sendCommand(OFF)                                                     // wenn Flur_2 AN -> dann AUS
            logInfo("flur","--- SICHERHEIT--Flur_2 wurde nach 35 sec AUS-geschaltet ---")
        }
    ])
end
Da die Timervariable nie auf null geprüft wird und die Rule einen vorhandenen Timer eh cancelt, kann man getrost auf den ganzen Müll verzichten ;)
nStep hat hier nur zwei wichtige Zustände, 1 oder 2. Darüber kann der Timer erkennen, ob er nun zum ersten oder zu zweiten Mal aufgerufen wurde. Man könnte statt des && auch verschachtelte If-Statements verwenden, es erscheint mir so aber übersichtlicher.

Zum logInfo möchte ich noch ein Wort verlieren (ich hab das an anderer Stelle auch schon ausführlichst erläutert...) Der erste String ist der Logger Name, bzw. der letzte Teil des Logger Namens. Dieser Teil wird an den Hauptnamen angehängt (org.openhab.model.script.) Anhand des ersten (nicht änderbaren) Teils kann man auch ableiten, wie der Loggername ausgeführt werden sollte. Natürlich kann man Großbuchstaben und Unterstriche verwenden, und auch superkalifragilistixexpialigetisch als Logger Namen verwenden, kurz und prägnant ist aber sinnvoller.

Die aufgeführten Logzeilen sind eher logDebug() :) aber das zöge natürlich eine Konfiguration in der Karaf Konsole nach sich.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
Steinspiel
Beiträge: 396
Registriert: 28. Dez 2019 08:49
Answers: 2

Re: Wieso funktioniert mein Timer nicht?

Beitrag von Steinspiel »

udo1toni hat geschrieben: 20. Mai 2020 22:03 Im Grunde reicht hier ein Timer. Das Ganze ist eine kleine StateMachine.
[...]
Moin,

Deine Lösung ist auch schön kompackt, funktioniert und ich habe sie übernommen. Danke erst mal dafür.
Zum Verständniss für mich noch ne Nachfrage:

Code: Alles auswählen

      
logInfo("flur","--- SICHERHEIT--Flur_1 Gedenksekunde für 5 sec gesetzt ---")
tFlur_SICHERHEIT = createTimer(now.plusSeconds(5), [|                                    // Timer auf 5 sec anlegen
nStep = nStep + 1
Nach setzen des ersten Timers wird nStep von "0" auf "1" erhöht,

Code: Alles auswählen

if(nStep == 1 && Flur1_Power.state == OFF) {                                         // wenn Flur_1 AUS
logInfo("flur","--- SICHERHEIT--Flur_1 ist AUS-geschaltet Timer auf 35 sec ---")
tFlur_SICHERHEIT.reschedule(now.plusSeconds(35))                                 // Timer auf 35 sec anlegen
} 
Wenn nStep "1" und Flur_1 AUS ist, wird der zweite Timer gesetzt. "reschedule" bedeutet sowas wie "Timer neu setzen" ?

Code: Alles auswählen

else if(nStep == 1 && Flur1_Power.state == ON) {
logInfo("flur","--- SICHERHEIT--Flur_1 ist AN-geschaltet Timer nicht gestartet ---")
}
Sonst nStep "1" und Flur_1 AN, passsiert nichts,

Code: Alles auswählen

else if(nStep == 2 && Flur2_Power.state == ON) {
Flur2_Power.sendCommand(OFF)                                                     // wenn Flur_2 AN -> dann AUS
logInfo("flur","--- SICHERHEIT--Flur_2 wurde nach 35 sec AUS-geschaltet ---")
}
Sonst, wenn nStep "2" und Flur_2 AN, dann AUS schalten, halbwegs richtig?
Nur, wie kann nStep "2" sein oder durch was wird es auf "2" erhöht, durch das zweite Aufrufen (reschedule) des Timers?

Zur LogInfo: Du hast bestimmt recht mit Deinen Argumenten. Ich hatte mir das selbst so ausklabüsert und immer den Namen der Rules Datei mit Underlines vorne weg geschrieben um alles eindeutiger zuordnen zu können.
bis dann, Steinspiel

Benutzeravatar
udo1toni
Beiträge: 15249
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Wieso funktioniert mein Timer nicht?

Beitrag von udo1toni »

nStep wird innerhalb des Timers hochgezählt.Du könntest natürlich auch außerhalb des Timers (also vor dem Timer) direkt die Variable auf 1 setzen und dann vor dem reschedule hochzählen. Die Statemachine könnte aber unterschiedliche reschedules verwenden, weshalb die auf jedne Fall auszuführenden Arbeiten pro Timeraufruf (also z.B. das Hochzählen) zu Beginn erledigt werden.
reschedule ist wörtlich zu nehmen, also "neu planen". reschedule funktioniert, solange der Timer noch nicht terminated hat (also das Lambda, der Code, verlassen wurde) .hasTerminated ist entsprechend auch eine Funktion von Timern, so wie .reschedule() oder .cancel und verrät, ob der Timer bereits abgelaufen ist (hier spielt das aber keine Rolle).

Wie gesagt kann man natürlich die logger relativ beliebig bezeichnen, wobei die Benennung eher funktionsbezogen sein sollte, nicht ortsbezogen. Wie erwähnt kann man jeden Logger einzeln steuern, also z.B. den Logger org.openhab.model.script.flur auf DEBUG laufen lassen, während org.openhab.model.script.wohnzimmer auf WARN läuft und die übrigen rulebezogenen Logger (also org.openhab.model.script.*) laufen auf default (das wäre INFO).
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
Steinspiel
Beiträge: 396
Registriert: 28. Dez 2019 08:49
Answers: 2

Re: Wieso funktioniert mein Timer nicht?

Beitrag von Steinspiel »

Moin,
udo1toni hat geschrieben: 21. Mai 2020 01:19 nStep wird innerhalb des Timers hochgezählt.
[...]
Ja, ich denke das ist verständlich. Danke Dir...

schönen Feiertag...
bis dann, Steinspiel

Antworten