Hi there,
in my JavaScript (ECMAScript 2022+) rule I’m using a function to set a timer for different windows or doors to remind me that these are still open.
My goal is I want that for every itemName there is only one timer.
In the moment this is not the case. If I close and open a window three times and leave it open in the end I have 3 timers running in the end.
Can some more professional programmer explain me how I can make the timers unique per itemName. Only the last timer started should exist.
this is the function were I start the timer:
function FensterErinnerung(itemName, delay, nachricht) {
timeoutReminderId = setTimeout(FensterNochOffen(itemName, nachricht), delay);
// ich möchte gerne das pro itemName nur ein Timer existieren kann.
// Aktuelles Problem, wenn ich das Fenster 3x zu und auf mache und es am ende auf ist,
// dann habe ich 3 aktive Timer laufen und dann 3 Durchsagen.
}
This is the whole code of my oeffnungen.js:
var { someFunction, durchsage } = require('oh_lib')
// Fensterauffunktion Heizung
function HeizungFensterAuf(raum) {
return function () {
console.debug("Heizung Fenster Auf Test", items.getItem("OC_" + raum).members.find(item => item.state === "OPEN"));
// Wenn immer noch OPEN wenn der Timer abgelaufen ist dann:
if (items.getItem("OC_" + raum).members.find(item => item.state === "OPEN") != undefined) // Prüft ob einer der Kinder von OC_Raum einen Zustand "ON" hat.
{
if (items.getItem("HT_" + raum + "_Fensterzustand", true) !== null) {
if (items.getItem("HT_" + raum + "_Fensterzustand").state === "CLOSED") {
items.getItem("HT_" + raum + "_Fensterzustand").sendCommand("OPEN");
console.debug("Fenster auf Modus aktiviert für", "HT_" + raum + "_Fensterzustand");
}
}
if (items.getItem("WT_" + raum + "_Fensterzustand", true) !== null) {
if (items.getItem("WT_" + raum + "_Fensterzustand").state === "CLOSED") {
items.getItem("WT_" + raum + "_Fensterzustand").sendCommand("OPEN");
console.debug("Fenster auf Modus aktiviert für", "WT_" + raum + "_Fensterzustand");
}
}
}
};
}
// Fensterzufunktion Heizung
function HeizungFensterZu(raum) {
if (items.getItem("HT_" + raum + "_Fensterzustand", true) !== null) {
if (items.getItem("HT_" + raum + "_Fensterzustand").state === "OPEN") {
items.getItem("HT_" + raum + "_Fensterzustand").sendCommand("CLOSED");
console.debug("Fenster auf Modus deaktiviert für", "HT_" + raum + "_Fensterzustand");
}
}
if (items.getItem("WT_" + raum + "_Fensterzustand", true) !== null) {
if (items.getItem("WT_" + raum + "_Fensterzustand").state === "OPEN") {
items.getItem("WT_" + raum + "_Fensterzustand").sendCommand("CLOSED");
console.debug("Fenster auf Modus deaktiviert für", "WT_" + raum + "_Fensterzustand");
}
}
}
// Fenstersteuerung Heizung Master
function HeizungFensterZustand(newState, raum, delay) {
// Wenn länger als 2min OPEN dann Heizung FensterAufModus aktivieren
if (newState === "OPEN") {
// Timer wenn Tür länger auf als delay ms, dann Fenster auf Zustand aktivieren
timeoutId = setTimeout(HeizungFensterAuf(raum), delay)
}
// Wenn CLOSED Heizung FensterAufModus deaktivieren
if (newState === "CLOSED") {
const members = items.getItem("OC_" + raum).members
const found = members.some(el => el.state === "OPEN");
if (!found) {
HeizungFensterZu(raum)
}
}
}
/* vvvvvvvvvv FENSTER AUF REMINDER FUNKTIONEN vvvvvvvvvv */
// Prüft ob nach Ablauf des Timers das Fenster noch offen ist
function FensterNochOffen(itemName, nachricht) {
return function () {
if (items.getItem(itemName).state === "OPEN") {
durchsage(["Arbeitszimmer", "Diele", "Werkstatt", "Wohnzimmer"], nachricht)
}
};
}
function FensterErinnerung(itemName, delay, nachricht) {
timeoutReminderId = setTimeout(FensterNochOffen(itemName, nachricht), delay);
// ich möchte gerne das pro itemName nur ein Timer existieren kann.
// Aktuelles Problem, wenn ich das Fenster 3x zu und auf mache und es am ende auf ist,
// dann habe ich 3 aktive Timer laufen und dann 3 Durchsagen.
}
/* ^^^^^^^^^^ FENSTER AUF REMINDER FUNKTIONEN ^^^^^^^^^^ */
rules.JSRule({
name: "Außentür oder Fenster auf oder zu",
description: "Automatisierungen abhängig von der Öffnungen von Außentüren und Fenstern",
triggers: [
triggers.GroupStateChangeTrigger('Aussentueren'),
triggers.GroupStateChangeTrigger('Fenster')
],
execute: (event) => {
loggerName = 'tueren.js.Oeffnungen';
console.debug("Automatisierung gestartet durch:", event.itemName, event.newState);
const triggerTyp = event.itemName.split('_')[0]
const raum = event.itemName.split('_')[1]
const triggerEigenschaft = event.itemName.split('_')[2]
var delay = 0
if (items.getItem(event.itemName).type === "ContactItem" && triggerTyp === "Aussentuer" || triggerTyp === "Fenster") {
if (triggerTyp === "Fenster" && event.newState === "OPEN") {
// Wenn (Lüften nicht empfohlen) => Zusätzliche Durchsage, dass Lüften nicht gut aktuell
if (items.getItem("LuftfeuchteEmpfehlung_" + raum, true) !== null) {
if (items.getItem("LuftfeuchteEmpfehlung_" + raum).state == 0) {
durchsage([raum], "Lüften im Raum " + raum + " wird bei der aktuellen Luftfeuchtigkeit außen nicht empfohlen.")
}
}
if (items.getItem("TemperaturIst_Outdoor").numericState < 10 || items.getItem("TemperaturIst_Outdoor").numericState > 25) {
// Wenn draussen sehr kalt (<10 Grad) || sehr heiss (> 25 Grad) => Timer nach 10 Min
if (items.getItem("TemperaturIst_Outdoor").numericState < 10) {
// Wenn draussen < 10 Grad
delay = 10 * 60 * 1000; //Erste Zahl entspricht den Minuten
FensterErinnerung(event.itemName, delay, "Das Fenster in Raum " + raum + " ist seit " + Math.round(delay / 60000) + " Minuten offen und draussen ist es sehr kalt.")
delay = 15 * 60 * 1000; //Erste Zahl entspricht den Minuten
FensterErinnerung(event.itemName, delay, "Das Fenster in Raum " + raum + " ist immer noch auf. Nun seit " + Math.round(delay / 60000) + " Minuten, obwohl es draussen sehr kalt ist.")
}
else {
// Wenn draussen > 25 Grad
delay = 10 * 60 * 1000; //Erste Zahl entspricht den Minuten
FensterErinnerung(event.itemName, delay, "Das Fenster in Raum " + raum + " ist seit " + Math.round(delay / 60000) + " Minuten offen und draussen ist es sehr warm.")
delay = 15 * 60 * 1000; //Erste Zahl entspricht den Minuten
FensterErinnerung(event.itemName, delay, "Das Fenster in Raum " + raum + " ist immer noch auf. Nun seit " + Math.round(delay / 60000) + " Minuten, obwohl es draussen sehr warm ist.")
}
}
else if (items.getItem("TemperaturIst_Outdoor").numericState < 17 || items.getItem("TemperaturIst_Outdoor").numericState > 23) {
// Wenn draussen kalt (<17 Grad) || heiss (> 23 Grad) => Timer nach 20 Min
delay = 20 * 60 * 1000; //Erste Zahl entspricht den Minuten
FensterErinnerung(event.itemName, delay, "Das Fenster in Raum " + raum + " ist seit " + Math.round(delay / 60000) + " Minuten offen.")
}
else {
// Wenn draussen 17 - 23 Grad => Timer nach 60 Min
delay = 60 * 60 * 1000; //Erste Zahl entspricht den Minuten
FensterErinnerung(event.itemName, delay, "Das Fenster in Raum " + raum + " ist seit " + Math.round(delay / 60000) + " Minuten offen.")
}
}
// Verschiedene Regeln je nach Raum dessen Fenster/Tür geöffnet wurde:
switch (raum) {
case "Arbeitszimmer":
if (triggerTyp === "Aussentuer") {
HeizungFensterZustand(event.newState, raum, 120000)
}
else {
HeizungFensterZustand(event.newState, raum, 0)
}
//Regeln nur für Türen:
if (triggerTyp === "Aussentuer") {
// Wenn OPEN & dunkel dann Lichttimer an
if (event.newState === "OPEN" && items.getItem("LS_Outdoor_DunkelMax").state === "ON") {
console.debug("Licht_Terrasse_Wand_Timer ON, da Tür auf und draussen dunkel")
items.getItem("Licht_Terrasse_Wand_Timer").sendCommand("ON");
console.debug("Licht_Westfassade_Spots_Timer ON, da Tür auf und draussen dunkel")
items.getItem("Licht_Westfassade_Spots_Timer").sendCommand("ON");
}
}
break;
case "Diele":
if (triggerTyp === "Aussentuer") {
HeizungFensterZustand(event.newState, raum, 120000)
}
else {
HeizungFensterZustand(event.newState, raum, 0)
}
//Regeln nur für Türen:
if (triggerTyp === "Aussentuer") {
// Wenn OPEN & dunkel dann Lichttimer an
if (event.newState === "OPEN" && items.getItem("LS_Outdoor_DunkelMax").state === "ON") {
console.debug("Licht_Einfahrt_Hauseingang_Timer ON, da Tür auf und draussen dunkel")
items.getItem("Licht_Einfahrt_Hauseingang_Timer").sendCommand("ON");
items.getItem("Licht_Einfahrt_Poller1_Timer").sendCommand(35);
items.getItem("Licht_Einfahrt_Poller2_Timer").sendCommand(35);
}
}
break;
case "Duschbad":
HeizungFensterZustand(event.newState, raum, 0)
break;
case "Hauswirtschaftsraum":
HeizungFensterZustand(event.newState, raum, 120000)
//Regeln nur für Türen:
if (triggerTyp === "Aussentuer") {
// Wenn OPEN & dunkel dann Lichttimer an
if (event.newState === "OPEN" && items.getItem("LS_Outdoor_DunkelMax").state === "ON") {
console.debug("Licht_Einfahrt_Hauseingang_Timer ON, da Tür auf und draussen dunkel")
items.getItem("Licht_Einfahrt_Hauseingang_Timer").sendCommand("ON");
}
}
break;
case "Kinderzimmer":
HeizungFensterZustand(event.newState, raum, 0)
//Regeln nur für Fenster:
if (triggerTyp === "Fenster") {
// Wenn OPEN Ost Dann Rolladen hoch
if (event.newState === "OPEN" && triggerEigenschaft === "Ost") {
console.debug("Rolladen hoch in Raum " + raum)
items.getItem("Verdunkelung_Kinderzimmer_LevelSoll").sendCommand(0);
}
}
break;
case "Kueche":
HeizungFensterZustand(event.newState, raum, 0)
break;
case "Schlafzimmer":
HeizungFensterZustand(event.newState, raum, 0)
//Regeln nur für Fenster:
if (triggerTyp === "Fenster") {
// Wenn OPEN Ost Dann Rolladen hoch
if (event.newState === "OPEN" && triggerEigenschaft === "Ost") {
console.debug("Rolladen hoch in Raum " + raum)
items.getItem("Verdunkelung_Schlafzimmer_LevelSoll").sendCommand(0);
}
}
break;
case "Wohnzimmer":
HeizungFensterZustand(event.newState, raum, 120000)
//Regeln nur für Türen:
if (triggerTyp === "Aussentuer") {
// Wenn OPEN & dunkel dann Lichttimer an
if (event.newState === "OPEN" && items.getItem("LS_Outdoor_DunkelMax").state === "ON") {
console.debug("Licht_Terrasse_Wand_Timer ON, da Tür auf und draussen dunkel")
items.getItem("Licht_Terrasse_Wand_Timer").sendCommand("ON");
}
}
break;
default:
console.warn("Raum " + raum + " ist für Öffnungsregeln aktuell noch nicht vorgesehen.")
}
}
else {
console.error("Automatisierung beendet, da erstes Segment des auslösenden Items nicht `Aussentuer` oder `Fenster` lautet.")
}
},
tags: ["Oeffnungen", "Aussentueren", "Fenster", "Licht", "Heizung", "Alarm"],
id: "Oeffnungen"
});