Timer variable setzen

Für welche Projekte verwendet Ihr OpenHAB? Was habt Ihr automatisiert? Stellt eure Projekte hier vor.

Moderatoren: Cyrelian, seppy

Antworten
ralfsfritz
Beiträge: 9
Registriert: 15. Jan 2020 17:30

Timer variable setzen

Beitrag von ralfsfritz »

Hallo zusammen, ich verwende zur Zeit häufig die Funktion " createTimer(now.plusMinutes(XXX()) ", um bestimmte Abläufe zeitlich zu begrenzen, z.B. Badezimmerlüfter usw. Nun möchte ich den Wert "xxx" variablel über einen Setpoint in der Sitemap eingeben,

Sitemap:

Code: Alles auswählen

Setpoint    item=Min_set_time01        icon="time"   step=1 minValue=0 maxValue=60
Items:

Code: Alles auswählen

Number   Min_set_time01
rule:

Code: Alles auswählen

rule "Lüfter Timer "
     when  
            Item HMIPSchalter_11_Switch changed from OFF to ON
    then
        createTimer(now.plusMinutes(xxx))
            [
            sendCommand(HMIPSchalter_11_Switch, "OFF")
            ]
    end
Wie kann ich nun den Wert "xxx" durch den aktuellen Wert des Items ersetzen?
Ich habe schon einiges versucht , bekomme es aber nicht hin, stehe irgendwie auf dem Schlauch..
Danke für eure Bemühungen.

int5749
Beiträge: 1161
Registriert: 4. Nov 2019 22:08
Answers: 9

Re: Timer variable setzen

Beitrag von int5749 »

ralfsfritz hat geschrieben: 24. Apr 2022 11:47 Danke für eure Bemühungen.
Hilfreich wäre die Formatierung von Code als Code ;-) Dazu bietet der erweiterte Editor eine entsprechende Funktion an ;)

Versuche doch mal

Code: Alles auswählen

rule "Lüfter Timer "
when
    Item HMIPSchalter_11_Switch changed from OFF to ON
then
    createTimer(now.plusMinutes(Min_set_time01))
    [
    sendCommand(HMIPSchalter_11_Switch, "OFF")
    ]
end
Evtl. muss auch explizit der State genutzt werden

Code: Alles auswählen

rule "Lüfter Timer "
when
    Item HMIPSchalter_11_Switch changed from OFF to ON
then
    createTimer(now.plusMinutes(Min_set_time01.state))
    [
    sendCommand(HMIPSchalter_11_Switch, "OFF")
    ]
end
VG
openHAB 4.1.0 Release mit openHABian in einem Debian Bookworm (LXC) unter Proxmox 8.1.3

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

Re: Timer variable setzen

Beitrag von udo1toni »

Es muss immer explizit der Status verwendet werden. Ein Item ist ein Item.
Ausgehend von Deiner Rule (ich habe mal die Code-Tags ergänzt...):

Code: Alles auswählen

// Globale Variablen werden zu Beginn der Datei definiert, vor der ersten Rule
var Timer tLuefter = null             // Objektvariable für Timer

rule "Lüfter Timer"
when
    Item HMIPSchalter_11_Switch changed from OFF to ON
then
    var Integer iTime = 5                  // Default Wert, falls irgendwas schief gegangen ist und kein gültiger Wert geliefert wird
    if(Min_set_time01.state instanceof Number)              // Falls Itemstatus eine gültige Zahl ist 
        iTime = (Min_set_time01.state as Number).intValue               // setze die Variable auf den Wert
    tLuefter?.cancel                                     // Stoppe einen eventuell laufenden Timer
    tLuefter = createTimer(now.plusMinutes(iTime), [|              // Erzeuge den Timer
        HMIPSchalter_11_Switch.sendCommand(OFF)
    ])
end
Der Code oben kann getrost als Minimum angesehen werden, auch wenn Dein Code grundsätzlich funktioniert. Aber.

Was passiert, wenn der schalter mehrfach hintereinander ein- und wieder ausgeschaltet wird und erst dann auf ON stehen bleibt? Antwort: es wird für jeden Einschaltvorgang ein Eintrag im Scheduler erzeugt. Der Scheduler speichert beliebig viele Einträge und führt diese alle zum genannten Zeitpunkt aus, es werden dann also mehrfach OFF-Befehle gesendet.
Das kann man zuverlässig verhindern, indem man den Timer an ein Objekt bindet, mit dem man den Timer dann abbrechen kann. Die Schreibweise

Code: Alles auswählen

tLuefter?.cancel
ist gleichbedeutend mit dem Code

Code: Alles auswählen

if(tLuefter !== null) tLuefter.cancel
Was bedeutet: Falls das Objekt tLuefter nicht auf null zeigt (!==), lösche den passenden Eintrag aus dem Scheduler.
Wenn tLuefter noch nicht initialisiert wurde (tLuefter = createTimer...), so wird das .cancel auch nicht ausgeführt. Dafür sorgt das ?.

Ein Item kann immer einen ungültigen Wert enthalten, zu jedem Zeitpunkt. Deshalb ist es wirklich wichtig, immer zu prüfen, ob der Itemstatus zum erwarteten Wert passt, also in diesem Fall, ob der Status eine Zahl ist.
Falls das nicht der Fall ist, sollte sich die Rule in diesem Fall vermutlich nicht einfach still verabschieden, sondern einen Fallback auf einen Default Wert machen.

Code: Alles auswählen

plusMinutes(long)
erwartet einen Long-Wert. Integer dürfte allerdings vollkommen ausreichen, openHAB macht dann aus dem Integer automatisch ein Long.

Schreibweise

Code: Alles auswählen

HMIPSchalter_11_Switch.sendCommand(OFF)
vs.

Code: Alles auswählen

sendCommand("HMIPSchalter_11_Switch","OFF")
oder

Code: Alles auswählen

sendCommand(HMIPSchalter_11_Switch,OFF)
Ersteres ist die Methode, welche im Kontext des Items existiert. Deshalb weiß sie genau, welche Befehle zur Verfügung stehen, in jeder Form.
Letzteres ist die Action, welche zwingend zwei Strings als Parameter verlangt. Da ein Item ein Objekt ist, wird openHAB stillschweigend aus dem Item den String Item.name ableiten. Genauso wird es aus dem OnOffType Objekt stillschweigend per .toString den String "OFF" erzeugen. Das geht aber nur solange gut, wie beide Parameter Objekte sind. Nutzt man hier Primitives, knallt es. Allgemein wird die Verwendung der Methode empfohlen, wenn man nicht zwingend auf die Action angewiesen ist.

Meine Schreibweise von createTimer weicht ebenfalls ab. Beide Schreibweisen sind erlaubt, jedoch wird durch das Hineinziehen des Lambda in die Parameterliste deutlich, das der Code Teil des Timers ist.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

ralfsfritz
Beiträge: 9
Registriert: 15. Jan 2020 17:30

Re: Timer variable setzen

Beitrag von ralfsfritz »

:D
Super , vielen Dank udo1toni, hat sofort geklappt.
Nur das Item oder item.state einsetzen hatte ich auch schon erfolglos versucht.
Danke

Antworten