Magnetkontakt Gefrierschrank mit Warnung

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

Moderatoren: Cyrelian, seppy

Antworten
SaschaQ
Beiträge: 205
Registriert: 2. Mär 2020 13:50
Answers: 0

Magnetkontakt Gefrierschrank mit Warnung

Beitrag von SaschaQ »

Hallo zusammen,

ich habe einen Magnetkontakt an einen Gefrierschrank montiert und möchte nun realisieren, dass der Magnetkontakt beim erstmaligen öffnen 120 Sekunden wartet und dann eine Warnung im 2 Minuten Takt versendet, wenn dieser geöffnet bleibt. Ich habe dies bereits für einen Wassermelder realisiert aber da habe ich die Initialen 2 Minuten Wartezeit nicht drin. Grund ist hierfür, dass man den Gefrierschrank ja auch ohne Warnung für eine Zeit öffnen will :).

Hier ist mein Code, den ich bisher selber geschrieben habe. Vielleicht kann mir jemand helfen, wie ich das mit den 2 Minuten Wartezeit hinbekomme wenn der Gefrierschrank geöffnet wird und wenn dieser dann über die 2 Minuten hinaus geöffnet bleibt, dass die Warnung dann alle 2 Minuten kommt, bis er geschlossen wird. Ich wäre euch sehr dankbar:

Code: Alles auswählen


rule "Benachrichtigung Türkontakt Gefrierschrank"
when
    Item kg_abstellraum_gefrierschrank_mk_offen changed or
	Time cron "0 0/30 * 1/1 * ? *"
then
createTimer(now.plusSeconds(120), [ |

    tWarngefrierschrank?.cancel
    if(kg_abstellraum_gefrierschrank_mk_offen.state == OPEN) {
        tWarngefrierschrank = createTimer(now, [|
            sendBroadcastNotification("Achtung Gefrierschrank im Abstellraum offen, Bitte schließen!")
            tWarngefrierschrank.reschedule(now.plusMinutes(2))
        ])
    }
	])
end



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

Re: Magnetkontakt Gefrierschrank mit Warnung

Beitrag von udo1toni »

Du denkst zu kompliziert...

Code: Alles auswählen

// Globale Variablen zu Beginn der Datei definieren
var Timer tWarngefrierschrank = null

rule "Benachrichtigung Türkontakt Gefrierschrank"
when
    Item kg_abstellraum_gefrierschrank_mk_offen changed          // Türkontakt Zustandsänderung
then
    tWarngefrierschrank?.cancel                                  // Falls Timer existiert, Timer abbrechen
    if(newState != OPEN)                                         // Falls Gefrierschrank nicht offen
        return;                                                  // Regel beenden

    tWarngefrierschrank = createTimer(now.plusMinutes(2), [|     // initiale Wartezeit 2 Minuten
        sendBroadcastNotification("Achtung! Gefrierschrank im Abstellraum offen, bitte schließen!")
        tWarngefrierschrank.reschedule(now.plusMinutes(2))       // Wiederholung nach 2 Minuten
    ])
end
openHAB arbeitet eventbasiert. Das hier entscheidende Event ist das Öffnen oder Schließen des Gefrierschranks. Es gibt keine zeitliche Relevanz!
Die Rule muss also exakt dann ausgelöst werden. wenn sich der Zustand des Kontakts ändert, sonst nie. *)

Wann immer der Kontakt seinen Zustand ändert, kann der Timer abgebrochen werden, denn entweder wurde die Tür geöffnet, dann dürfte es eigentlich noch gar keinen Timer geben, oder die Tür wurde geschlossen, dann braucht es keine Warnmeldung.
Das ? am Ende der Timer Variablen lässt den nachfolgenden Befehl cancel nur ausführen, wenn die Variable nicht auf null verweist, die Variable also initialisiert ist. Ohne das ? käme bei nicht initialisierter Variable eine Fehlermeldung.

Falls der Kontakt nicht OPEN meldet, kann die Rule abgebrochen werden.

Ansonsten wurde gerade der Gefrierschrank geöffnet und der Timer muss angelegt werden. Damit ist die Rule dann beendet.

Läuft der Timer ab, so wird die Warnmeldung ausgegeben und der Timer wird erneut geplant,

Mehr braucht es nicht :)
Die Rule für den Wasseralarm kannst Du exakt genauso bauen, Du änderst dann lediglich die erste Timerzeit ab. z.B. auf now.plusSeconds(1).

Übrigens sind 2 Minuten für einen Gefrierschrank in etwa 3 Ewigkeiten. Mein Tipp wären eher 45 Sekunden als reguläre Alarmzeit. Unser Liebherr fängt nach 30 Sekunden mit seinem Radau an, der Samsung Kühlschrank braucht etwa eine Minute, das erreiche ich höchstens, wenn ich den Großeinkauf einräume.
Die Folgealarme können dann trotzdem alle 2 Minuten kommen, das sind ja zwei verschiedene Parameter innerhalb der Rule.

*) Einschränkung: solange openHAB normal läuft. Beim Einlesen der rules-Datei wird die Timer-Variable neu initialisiert, in der Folge wird ein laufender Timer "unkontrollierbar", d.h. es kommt zu exakt einer Warnmeldung, aber das reschedule wird nicht erfolgreich sein.
Falls Du auf einer aktuellen (5.0+) Version bist, könntest Du auch den private Cache verwenden:

Code: Alles auswählen

rule "Benachrichtigung Türkontakt Gefrierschrank"
when
    Item kg_abstellraum_gefrierschrank_mk_offen changed                               // Türkontakt Zustandsänderung
then
    (privateCache.remove('TK_Alarm') as Timer)?.cancel                                // eventuell laufenden Timer entfernen
    if(newState != OPEN)                                                              // Falls Gefrierschrank nicht offen
        return;                                                                       // Regel beenden

    privateCache.put('TK_Alarm', createTimer(now.plusSeconds(120), [|                 // initiale Wartezeit 2 Minuten
        sendBroadcastNotification("Achtung! Gefrierschrank im Abstellraum offen, bitte schließen!")
        (privateCache.get('TK_Alarm') as Timer).reschedule(now.plusMinutes(2)))       // Wiederholung nach 2 Minuten
    ]))
end
Da ein Cache alle möglichen Objekte enthalten kann, benötigt openHAB hier einen Hint (das Casting nach Timer).
.remove liefert den alten Wert, falls der Cache existierte, ansonsten null. Entsprechend funktioniert der Aufruf identisch zur Timer Variablen.
Beim Anlegen wird der Cache mit dem Timer Object gefüllt.
Das Reschedule funktioniert dann genau wie zuvor, aber auch hier braucht openHAB einen Tipp, was das denn für eine Objekt ist, damit .reschedule überhaupt zur Verfügung steht.

Beide Rules habe ich auf meinem Stage-System getestet.
Produktiv habe ich noch nicht auf private/sharedCache umgestellt, aber in der Theorie sollte der Cache - im Gegensatz zur globalen Variablen - eine Reinitialisierung überleben.
openHAB5.1.2 stable in einem Debian-Container (trixie, OpenJDK 21 headless runtime - LXC, 4 Kerne, 3 GByte RAM)
Hostsystem Proxmox VE 9.1.5 - AMD Ryzen 5 3600 6 Kerne, 12 Threads - 64 GByte RAM - ZFS Pools: Raid Z1, 3 x 20 TB HDD -> 40 TByte und Raid Z0-Mirrored 4 x 1 TByte NVMe -> 2 TByte

Antworten