Timer

Allgemeine Fragen rund um die "Smart Home" Hardware/Komponenten

Moderatoren: seppy, udo1toni

shuo
Beiträge: 181
Registriert: 1. Sep 2018 18:24

Timer

Beitrag von shuo »

Hallo zusammen,
ich habe einen Timer für meine Bewässerung am Laufen.
Grundsätzlich funktionert alles soweit. Ich stehe gerade auf dem Schlauch und verstehe nicht warum das Licht bei Timer-1Min anfängt und bei -1 aufhört.
Also wenn ich 15 Min einstelle, dann schaltet sich das Licht bei 14 ein und hört bei -1 auf.
Außerdem funktionert das mit den Zeitstempeln irgendwie nicht....Was mache ich denn da noch falsch....Die Zeit zwischen Start und Stop ist exakt 1 Min. Sollte aber 15 sein...?

Code: Alles auswählen

rule "Watering Rasen for selected time"
when
    Item garden_Rasen_Timer_Selector changed
then

    var int int_garden_Rasen_Selection = (garden_Rasen_Timer_Selector.state as DecimalType).intValue
    if(garden_Rasen_Timer_Selector.state>=15){
        garden_Rasen_Timer_Remaining.postUpdate(int_garden_Rasen_Selection)
        if (timerA !== null) 
            timerA.cancel
            timerA = createTimer(now.plusMinutes(1),[
            garden_Rasen_Timer_Remaining.postUpdate((garden_Rasen_Timer_Remaining.state as Number).intValue - 1)
            if ((garden_Rasen_Timer_Remaining.state as Number).intValue !=0){
                timerA.reschedule(now.plusMinutes(1))
                postUpdate(garden_Rasen_Timer_DateTime_Start, new DateTimeType())
                postUpdate(garden_Rasen_Timer_DateTime_Stop, nullValue)
                Bad_UG_Light.sendCommand(ON)
            }
            else{
                Bad_UG_Light.sendCommand(OFF)
                postUpdate(garden_Rasen_Timer_DateTime_Stop,  new DateTimeType())
                postUpdate(garden_Rasen_Timer_Selector,0)
            }
        ])
    }
end
Sieht dann im Ergebnis so aus:
Rasen.PNG
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Zuletzt geändert von shuo am 5. Jun 2021 00:24, insgesamt 1-mal geändert.

shuo
Beiträge: 181
Registriert: 1. Sep 2018 18:24

Re: Timer

Beitrag von shuo »

Manchmal sieht man den Walt vor lauter Bäumen nicht mehr.
So funktionert es wie gewollt:

Code: Alles auswählen

rule "Watering Rasen for selected time"
when
    Item garden_Rasen_Timer_Selector changed
then

    var int int_garden_Rasen_Selection = (garden_Rasen_Timer_Selector.state as DecimalType).intValue

    if(garden_Rasen_Timer_Selector.state>=15){
        garden_Rasen_Timer_Remaining.postUpdate(int_garden_Rasen_Selection)
        if (timerA !== null) 
            timerA.cancel
                postUpdate(garden_Rasen_Timer_DateTime_Start, new DateTimeType())
                postUpdate(garden_Rasen_Timer_DateTime_Stop, nullValue)
                Bad_UG_Light.sendCommand(ON)
            timerA = createTimer(now.plusMinutes(1),[
            garden_Rasen_Timer_Remaining.postUpdate((garden_Rasen_Timer_Remaining.state as Number).intValue - 1)
            if ((garden_Rasen_Timer_Remaining.state as Number).intValue !=0){
                timerA.reschedule(now.plusMinutes(1))

            }
            else{
                Bad_UG_Light.sendCommand(OFF)
                postUpdate(garden_Rasen_Timer_DateTime_Stop,  new DateTimeType())
                postUpdate(garden_Rasen_Timer_Selector,0)
            }
        ])
    }
end
P.S: Nicht wundern, das ich schalte das Licht nur für Testzwecke ein und aus:)

shuo
Beiträge: 181
Registriert: 1. Sep 2018 18:24

Re: Timer

Beitrag von shuo »

Eine Frage hätte ich noch. Verstehe das nicht.
Sobald ich den Timer starte, und der Zeitstempel gesetzt wird, wird die Zeit von ein paar Min angezeigt. Sobald der Timer vollständig abgelaufen ist, wird diese mit der korrekten Zeit angezeigt....

Kann sich das jemand erklären?

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

Re: Timer

Beitrag von udo1toni »

Das liegt daran, dass Du die Stopzeit erst ins Item schreibst, wenn sie erreicht ist.

Grundsätzlich solltest Du versuchen, die Methoden zu verwenden, wann immer das möglich ist. Konstanten benötigen weniger Platz als Variablen (eher akademischer Natur, aber wenn wir schon dabei sind...) Vor der Verwendung eines Typs sollte man eine Typprüfung durchführen, sonst kommt es unter Umständen zu einer Nullpointer Exception.
openHAB arbeitet asynchron, das bedeutet, wenn Du innerhalb einer Rule einem Item einen Wert zuweist und anschließend ausliest, ist das Ergebnis nicht vorhersehbar, es kann der alte Wert zurückgeliefert werden oder auch der neue Wert. Entsprechend sollte man lieber mit einer lokalen Kopie des Wertes arbeiten.
Eine bedingte Verzweigung wirkt grundsätzlich nur auf den nächsten Befehl. Soll mehr als ein Befehl übersprungen werden, müssen diese in {} eingeschlossen werden. Andererseits kann man die {} weg lassen, wenn es nur um einen Befehl geht.
Statt einen großen Block nur bedingt auszuführen, ist es sinnvoller, die Rule abzubrechen, falls die Bedingung nicht erfüllt ist.

Die Rule sähe also besser so aus:

Code: Alles auswählen

var Timer timerA = null

rule "Watering Rasen for selected time"
when
    Item garden_Rasen_Timer_Selector changed
then
    if(!(garden_Rasen_Timer_Selector.state instanceof Number))                            // Falls nicht vom Typ Number
       return;                                                                            // Rule abbrechen

    val Integer iDuration = (garden_Rasen_Timer_Selector.state as Number).intValue        // Wert in lokaler Konstanten speichern
    if(iDuration < 15)                                                                    // falls kleiner 15
        return;                                                                           // Rule abbrechen

    timerA?.cancel                                                                        // Falls ein Timer existiert, entfernen
    garden_Rasen_Timer_Remaining.postUpdate(iDuration)                                    // Dauer nach verbleibende Dauer übernehmen
    garden_Rasen_Timer_DateTime_Start.postUpdate(now.toLocalDateTime.toString)                            // Startzeit notieren
    garden_Rasen_Timer_DateTime_Stop.postUpdate(now.plusMinutes(iDuration).toLocalDateTime.toString)      // geplantes Ende notieren
    Bad_UG_Light.sendCommand(ON)                                                          // Verbraucher einschalten
    timerA = createTimer(now.plusMinutes(1),[                                             // Timer starten
        val Integer iRemain = (garden_Rasen_Timer_Remaining.state as Number).intValue - 1 // verbleibende Dauer berechnen
        garden_Rasen_Timer_Remaining.postUpdate(iRemain)                                  // und ins Item schreiben
        if(iRemain > 0)                                                                   // falls größer 0
            timerA.reschedule(now.plusMinutes(1))                                         // Timer erneut planen
        else                                                                              // ansonsten
            Bad_UG_Light.sendCommand(OFF)                                                 // Verbraucher ausschalten
    ])
end
Da die beiden Items garden_Rasen_Timer_DateTime_Start und garden_Rasen_Timer_DateTime_Stop vom Typ DateTime sind, ist es das Einfachste, den Wert über now zu bestimmen und mittels .toString zu konvertieren, dann steht auch plusMinutes als Funktion zur Verfügung.

Code ist wie immer ungetestet :) also keine Gelinggarantie, aber in der Theorie sollte es so gehen...

Edit: Code korrigiert, falls jemand die Rule findet und verwenden will...
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

shuo
Beiträge: 181
Registriert: 1. Sep 2018 18:24

Re: Timer

Beitrag von shuo »

Viele Dank Udo für die Erklärung. So im Nachhinein ist es klar...

Eine Frage dennoch. Du hast geschrieben:
es kann der alte Wert zurückgeliefert werden oder auch der neue Wert
Von was ist es denn abhängig welcher Wert zurückgeliefert wird?

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

Re: Timer

Beitrag von udo1toni »

shuo hat geschrieben: 5. Jun 2021 19:23 Von was ist es denn abhängig welcher Wert zurückgeliefert wird?
Vom Zufall. Wie erwähnt arbeitet openHAB asynchron. Das bedeutet in anderen Worten: In dem Moment, wo eine Rule ein .postUpdate sendet (oder auch ein .sendCommand) wird ein eigener Thread gestartet.
Jeder dieser Threads wird gestartet und die Rule, die ihn gestartet hat, läuft sofort weiter, ohne darauf zu warten, dass der gestartete Thread fertig ist (das ist ja der Sinn des Multitasking).
Gewöhnlich wird so eine Aktion (Manipulation eines Status auf dem openHAB Bus oder Senden eines Commands) deutlich unterhalb einer Millisekunde dauern, wenn das System gerade gut ausgelastet ist, können aber auch mehrere Dutzend Millisekunden zusammenkommen, das ist kein Fehlverhalten sondern by Design (und mit Absicht!).
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

shuo
Beiträge: 181
Registriert: 1. Sep 2018 18:24

Re: Timer

Beitrag von shuo »

Vielen Dank für die ausführliche Erklärung. Ist weitgehend klar. Muss ich jetzt "nur" noch umsetzen :D

shuo
Beiträge: 181
Registriert: 1. Sep 2018 18:24

Re: Timer

Beitrag von shuo »

Jetzt muss ich doch noch mal was fragen Udo.

In

Code: Alles auswählen

garden_Rasen_Timer_DateTime_Start
steht eine falsche Uhrzeit drin.

Code: Alles auswählen

garden_Rasen_Timer_DateTime_Stop
hingegen stimmt:
Rasen.png
Korrektur: Stoppzeit stimmt auch nicht.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

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

Re: Timer

Beitrag von udo1toni »

OH2 oder OH3?

Wie stimmt die Uhrzeit nicht? Ist es eine vollkommen verkehrte Zeit, oder ist sie z.B. um einen festen Wert verschoben (also z.B. beide Zeiten sind um exakt 2 Stunden verkehrt)?
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

shuo
Beiträge: 181
Registriert: 1. Sep 2018 18:24

Re: Timer

Beitrag von shuo »

OH3. Ist immer die selbe Zeit. Ich war Anfangs irritiert, weil beim ersten Versuch gestern die Stop-Zeit gepasst hatte. Seither immer die gleiche:

Start:

Code: Alles auswählen

 Samstag, 05.06.2021 00:24:20 
Stop:

Code: Alles auswählen

 Samstag, 05.06.2021 21:07:53 

Antworten