const Skriptversion = "1.6.13" //vom 29.06.2021 - https://github.com/Pittini/iobroker-Fensterauswertung - https://forum.iobroker.net/topic/31674/vorlage-generisches-fensteroffenskript-vis
//Script um offene Fenster/Türen pro Raum und insgesamt zu zählen.
//Möglichkeit eine Ansage nach x Minuten einmalig oder zyklisch bis Fensterschließung anzugeben
//Dynamische erzeugung einer HTML Übersichtstabelle
//WICHTIG!!!
//Vorraussetzungen: Den Geräten müssen Räume zugewiesen sein, sowie die Funktion "Fenster" bzw "Tuer" für jeden entsprechenden Datenpunkt.
//Grundeinstellungen
const logging = true; //Erweiterte Logs ausgeben?
const praefix = "javascript.0.FensterUeberwachung."; //Grundpfad für Script DPs - Muß innerhalb javascript.x sein.
const PresenceDp = "" //Pfad zum Anwesenheitsdatenpunkt, leer lassen wenn nicht vorhanden
const WhichWindowFunctionToUse = "Fenster"; // Legt fest nach welchem Begriff in Funktionen gesucht wird. Diese Funktion nur dem Datenpunkt zuweisen, NICHT dem ganzen Channel!
const WhichDoorFunctionToUse = "Tuer"; // Legt fest nach welchem Begriff in Funktionen gesucht wird. Diese Funktion nur dem Datenpunkt zuweisen, NICHT dem ganzen Channel!
const WindowIgnoreTime = 10000; // 10000 ms = 10 Sekunden - Zeit in ms für die kurzzeitiges öffnen/schliessen ignoriert wird
const DoorIgnoreTime = 5000; // 1000 ms = 1 Sekunden - Zeit in ms für die kurzzeitiges öffnen/schliessen ignoriert wird
//Nachrichteneinstellungen
const TimeToMsg = 1200000 // 300000 ms = 5 Minuten - Zyklus- bzw. Ablaufzeit für Tür/Fenster-offenwarnung/en
const MaxMessages = 5; //Maximale Anzahl der Nachrichten pro Raum
const MaxMessages = 1; //Maximale Anzahl der Nachrichten pro Raum
//Telegram
const UseTelegram = false; // Sollen Nachrichten via Telegram gesendet werden?
//Pushover
const UsePushover = false; // Sollen Nachrichten via PushOver gesendet werden?
const PushOverInstance = "pushover.0"; //Pushoverinstanz welche genutzt werden soll angeben
const PushOverDevice = "All"; //Welches Gerät soll die Nachricht bekommen
const PushOverTitle = "Fensterüberwachung";
const PushOverSound = "none"; //Welcher Sound soll abgespielt werden? "none" für kein Sound, "" für Standartsound, ansonsten Namen angeben z.B. "magic"
//Alexa
const UseAlexa = false; // Sollen Nachrichten via Alexa ausgegeben werden?
const AlexaInstance = "alexa2.0";
const AlexaId = ""; // Die Alexa Seriennummer.
const AlexaVolume = "50"; // Lautstärke der Nachrichten. Wert von 1 bis 100
//Other
const UseMail = false; //Nachricht via Mail versenden?
const UseSay = false; // Sollen Nachrichten via Say ausgegeben werden? Developerfunktion, muß deaktiviert sein.
const UseEventLog = false; // Sollen Nachrichten ins Eventlog geschreiben werden? Developerfunktion, muß deaktiviert sein.
const NoMsgAtPresence = false; //Sollen Nachrichten bei Anwesenheit unterdrückt werden?
//Tabelleneinstellungen
const DoorOpenImg = "/icons-mfd-svg/fts_door_open.svg"; //Icon für Tür offen
const DoorCloseImg = "/icons-mfd-svg/fts_door.svg"; // Icon für Tür geschlossen
const DoorTiltedImg = "/icons-mfd-svg/fts_door_tilt.svg" // Icon für Tür gekippt
const WindowOpenImg = "/icons-mfd-svg/fts_window_1w_open.svg"; //Icon für Fenster offen
const WindowCloseImg = "/icons-mfd-svg/fts_window_1w.svg"; // Icon für Fenster geschlossen
const WindowTiltedImg = "/icons-mfd-svg/fts_window_1w_tilt.svg" //Icon für Fenster gekippt
const WindowOpenTiltedImg = "/icons-mfd-svg/fts_window_2w_open_l_tilt_r.svg" //Icon für offen und gekippt in einem Raum gleichzeitig
const VentImg = "/icons-mfd-svg/vent_ventilation.svg"; //Icon für Lüftungsinfo
const ImgInvert = 1; // Bildfarben invertieren? Erlaubte Werte von 0 bis 1
const OpenWindowColor = "#f44336"; // Farbe für Fenster offen
const OpenDoorColor = "darkorange"; //Farbe für Tür offen
const TiltedWindowColor = "#F56C62"; //Farbe für gekippte Fenster o. Tür/en
const ClosedWindowColor = "#4caf50"; // Farbe für geschlossene Fenster o. Tür/en
const VentWarnColor = "#ffc107"; // Farbe für Lüftungswarnung
const ShowCaptionTbl = false; // Überschrift anzeigen?
const ShowSummaryTbl = true; // Zusammenfassung anzeigen?
const ShowDetailTbl = true; // Details anzeigen?
const RoomSortMode = 1; //0= Raumliste unsortiert, 1= alpabetisch sortiert, 2= Benutzerdefinierte Sortierung
//Logeinstellungen
const MaxLogEntrys = 20; //Maximale Anzahl der zu speichernden Logeinträge
const AutoAddTimestamp = true; //Soll den geloggten Nachrichten automatisch ein Zeitsempel zugeordnet werden?
const LogTimeStampFormat = "TT.MM.JJJJ SS:mm:ss"; //Zeitformatierung für Log Zeitstempel
const LogEntrySeparator = "
"; //Trennzeichen für Logeinträge
//Ab hier nix mehr ändern!
const SendVentMsg = [];
const SendDoorOpenCloseMsg = [];
const SendWindowOpenCloseMsg = [];
const SendWindowWarnMsg = [];
const SendDoorWarnMsg = [];
const OpenWindowListSeparator = "
"; //Trennzeichen für die Textausgabe der offenen Fenster pro Raum
const WindowIsOpenWhen = ["true", "offen", "open", "opened", "2"]; // Hier können eigene States für offen angegeben werden, immer !!! in Kleinschreibung
const WindowIsClosedWhen = ["false", "geschlossen", "closed", "0"]; // Hier können eigene States für geschlossen angegeben werden, immer !!! in Kleinschreibung
const WindowIsTiltedWhen = ["tilted", "gekippt", "1"]; // Hier können eigene States für gekippt angegeben werden, immer !!! in Kleinschreibung
let OpenDoorCount = 0; // Gesamtzahl der geöffneten Türen
let TiltedDoorCount = 0; // Gesamtzahl der gekippten Türen
let OpenWindowCount = 0; // Gesamtzahl der geöffneten Fenster
let TiltedWindowCount = 0; // Davon Anzahl der gekippten Fenster
const RoomOpenCount = []; // Array für Summe geöffneter Verschlüsse pro Raum
const RoomOpenDoorCount = []; // Array für Zähler offene Türen pro Raum
const RoomTiltedDoorCount = []; // Array für Zähler gekippte Türen pro Raum
const RoomOpenWindowCount = []; // Array für Zähler offene Fenster pro Raum
const RoomTiltedWindowCount = []; // Array für Zähler gekippte Fenster pro Raum
const RoomWindowMsgCount = []; //Zähler für bereits ausgegebene Fenster Warnmeldungen
const RoomDoorMsgCount = []; //Zähler für bereits ausgegebene Tür Warnmeldungen
let RoomHas = [] // 0=Weder Tür noch Fenster, 1 Tür, 2 Fenster, 3 Tür und Fenster
const RoomsWithCombinedOpenings = [];
let RoomsWithOpenings = ""; // Kombinierte Liste mit offenen Türen und Fenstern
let RoomsWithOpenDoors = ""; //Liste der Räume mit offenen Türen
let RoomsWithTiltedDoors = ""; //Liste der Räume mit offenen Türen
let RoomsWithOpenWindows = ""; //Liste der Räume mit offenen Fenstern
let RoomsWithTiltedWindows = ""; //Liste der Räume mit gekippten Fenstern
let RoomsWithVentWarnings = []; //Räume mit Lüftungswarnung
let RoomListOrderPriority = ""; //Sortierreihenfolge der Raumliste
const OpenWindowMsgHandler = []; // Objektarray für timeouts pro Raum/Fenster
const OpenDoorMsgHandler = []; // Objektarray für timeouts pro Raum/Tür
const IgnoreValue = []; //Vergleichswert für IgnoreTimeout
const VentMsgHandler = []; //Timeout/Intervall Objekt
const VentMsg = []; //Lüftungsnachricht
const Sensor = []; //Sensoren als Array anlegen
let SensorType = []; //Unterscheidung zwischen Tür und Fenstersensor
const SensorVal = [];//Sensorwerte als Array anlegen
const SensorOldVal = []; //Alte Sensorwerte als Array ablegen
const WindowWarnRuntime = []; //Timer WindowWarnRuntime pro Fenster
const DoorWarnRuntime = []; //Timer DoorWarnRuntime pro Tür
const VentWarnTime = []; // Array mit Zeiten nach dem eine Lüftungsempfehlung ausgegeben wird
let RoomList = []; // Raumlisten Array
const RoomStateTimeStamp = []; //Letzte Änderung des Fenster-Raumstatus
const RoomStateTimeCount = []; // Zeitspanne seit letzter Änderung
const RoomDoorStateTimeStamp = []; //Letzte Änderung des Tür-Raumstatus
const RoomDoorStateTimeCount = []; // Zeitspanne seit letzter Änderung
let z = 0; //Zähler
let DpCount = 0; //Zähler
let IsInit = true // Marker - Wird nach initialisierung auf false gesetzt
// /** @type {{ id: string, initial: any, forceCreation: boolean, common: iobJS.StateCommon }[]} */
const States = []; // Array mit anzulegenden Datenpunkten
let Funktionen = getEnums('functions'); //Array mit Aufzählung der Funktionen
let MessageLog = ""; //Log der ausgegebenen Meldungen
let MuteMode = 0; //Stummschaltungsmodus für Nachrichten. 0=Alles erlaubt, 1=Sprachnachrichten deaktivieren, 2=Alles deaktivieren
let Presence = true; //Anwesenheit als gegeben initialisieren
const IgnoreInProcess = []; //Läuft gerade eine Überprüfung ob eine Statusänderung ignoriert werden muß?
let SensorCount = 0; //Hilfszähler weil y bei mehreren Funktionen mehrmals bei 0 beginnt
log("starting Fensterskript, Version " + Skriptversion);
for (let x in Funktionen) { // loop ueber alle Functions
let Funktion = Funktionen[x].name;
if (typeof Funktion == "undefined") {
log("Keine Funktion gefunden", "error");
}
else {
if (typeof Funktion == 'object') Funktion = Funktion.de;
let members = Funktionen[x].members;
if (Funktion == WhichWindowFunctionToUse || Funktion == WhichDoorFunctionToUse) { //Wenn Function ist Fenster oder Tür
for (let y in members) { // Loop über alle Fenster/Tür Members
Sensor[SensorCount] = members[y];
let room = getObject(Sensor[SensorCount], 'rooms').enumNames[0];
if (typeof room == 'object') room = room.de;
if (RoomList.indexOf(room) == -1) { //Raumliste ohne Raumduplikate und zugehörige Dps erzeugen
//Datenpunkte pro Raum vorbereiten
States[DpCount] = { id: praefix + room + ".RoomOrderPriority", initial: z, forceCreation: false, common: { read: true, write: true, name: "Raumpriorität für Tabelle", role: "state", type: "number", def: z } };
DpCount++;
States[DpCount] = { id: praefix + room + ".RoomOpenCount", initial: 0, forceCreation: false, common: { read: true, write: false, name: "Summe der geöffneten Fenster und Türen im Raum", role: "state", type: "number", def: 0 } };
DpCount++;
States[DpCount] = { id: praefix + room + ".RoomOpenDoorCount", initial: 0, forceCreation: false, common: { read: true, write: false, name: "Anzahl der geöffneten Türen im Raum", role: "state", type: "number", def: 0 } };
DpCount++;
States[DpCount] = { id: praefix + room + ".RoomTiltedDoorCount", initial: 0, forceCreation: false, common: { read: true, write: false, name: "Anzahl der gekippten Türen im Raum", role: "state", type: "number", def: 0 } };
DpCount++;
States[DpCount] = { id: praefix + room + ".RoomOpenWindowCount", initial: 0, forceCreation: false, common: { read: true, write: false, name: "Anzahl der geöffneten Fenster im Raum", role: "state", type: "number", def: 0 } };
DpCount++;
States[DpCount] = { id: praefix + room + ".RoomTiltedWindowCount", initial: 0, forceCreation: false, common: { read: true, write: false, name: "Anzahl der gekippten Fenster im Raum", role: "state", type: "number", def: 0 } };
DpCount++;
States[DpCount] = { id: praefix + room + ".SendVentMsg", initial: true, forceCreation: false, common: { read: true, write: true, name: "Sollen für diesen Raum Lüftungsnachrichten ausgegeben werden?", type: "boolean", role: "state", def: true } }; //
DpCount++;
States[DpCount] = { id: praefix + room + ".SendDoorOpenCloseMsg", initial: true, forceCreation: false, common: { read: true, write: true, name: "Sollen für diesen Raum Nachrichten bei öffnen/schliessen von Türen ausgegeben werden?", type: "boolean", role: "state", def: true } }; //
DpCount++;
States[DpCount] = { id: praefix + room + ".SendWindowOpenCloseMsg", initial: true, forceCreation: false, common: { read: true, write: true, name: "Sollen für diesen Raum Nachrichten bei öffnen/schliessen von Fenstern ausgegeben werden?", type: "boolean", role: "state", def: true } }; //
DpCount++;
States[DpCount] = { id: praefix + room + ".SendWindowWarnMsg", initial: true, forceCreation: false, common: { read: true, write: true, name: "Sollen für diesen Raum Nachrichten für überschrittene Fenster Öffnungszeit ausgegeben werden?", type: "boolean", role: "state", def: true } }; //
DpCount++;
States[DpCount] = { id: praefix + room + ".SendDoorWarnMsg", initial: true, forceCreation: false, common: { read: true, write: true, name: "Sollen für diesen Raum Nachrichten für überschrittene Tür Öffnungszeit ausgegeben werden?", type: "boolean", role: "state", def: true } }; //
DpCount++;
States[DpCount] = { id: praefix + room + ".WindowIsOpen", initial: false, forceCreation: false, common: { read: true, write: false, name: "Fenster im Raum offen oder gekippt?", type: "boolean", role: "state", def: false } }; //
DpCount++;
States[DpCount] = { id: praefix + room + ".DoorIsOpen", initial: false, forceCreation: false, common: { read: true, write: false, name: "Türen im Raum offen?", type: "boolean", role: "state", def: false } }; //
DpCount++;
States[DpCount] = { id: praefix + room + ".RoomIsOpen", initial: false, forceCreation: false, common: { read: true, write: false, name: "Raum offen?", type: "boolean", role: "state", def: false } }; //
DpCount++;
States[DpCount] = { id: praefix + room + ".VentWarnTime", initial: 0, forceCreation: false, common: { read: true, write: true, name: "Anzahl der Tage nach der eine Lüftungsempfehlung erzeugt wird", unit: "Tage", type: "number", role: "state", def: 0 } };
DpCount++;
//log(Funktion + ': ' + room);
RoomList[z] = room;
RoomOpenCount[z] = 0; // Array mit 0 initialisieren
RoomOpenDoorCount[z] = 0; // Array mit 0 initialisieren
RoomTiltedDoorCount[z] = 0; // Array mit 0 initialisieren
RoomOpenWindowCount[z] = 0; // Array mit 0 initialisieren
RoomTiltedWindowCount[z] = 0; // Array mit 0 initialisieren
RoomWindowMsgCount[z] = 0;
RoomDoorMsgCount[z] = 0;
WindowWarnRuntime[z] = 0; // Array mit 0 initialisieren
DoorWarnRuntime[z] = 0; // Array mit 0 initialisieren
RoomsWithCombinedOpenings[z] = []; //Zweite Dimension für jeden Raum initialisieren
z++;
};
let TempIndex = RoomList.indexOf(room);
if (Funktion == WhichWindowFunctionToUse) { //Fenster
if (typeof RoomHas[TempIndex] == "undefined") { //Für Raum festlegen ob Türen und/oder Fenster überwacht werden. Steuert ein/aus-blenden der Tabellenbilder
RoomHas[TempIndex] = 2; // 0=Weder Tür noch Fenster, 1 Tür, 2 Fenster, 3 Tür und Fenster
}
else if (RoomHas[TempIndex] == 1) {
RoomHas[TempIndex] = 3;
};
SensorType[SensorCount] = "Window";
} else if (Funktion == WhichDoorFunctionToUse) { //Tür
if (typeof RoomHas[TempIndex] == "undefined") { //Für Raum festlegen ob Türen und/oder Fenster überwacht werden. Steuert ein/aus-blenden der Tabellenbilder
RoomHas[TempIndex] = 1; // 0=Weder Tür noch Fenster, 1=Tür, 2=Fenster, 3=Tür+Fenster
}
else if (RoomHas[TempIndex] == 2) {
RoomHas[TempIndex] = 3;
};
SensorType[SensorCount] = "Door";
};
if (logging) {
if (RoomHas[TempIndex] == 1) log("Raum- " + TempIndex + " = " + RoomList[TempIndex] + " hat Türsensor/en");
if (RoomHas[TempIndex] == 2) log("Raum- " + TempIndex + " = " + RoomList[TempIndex] + " hat Fenstersensor/en");
if (RoomHas[TempIndex] == 3) log("Raum- " + TempIndex + " = " + RoomList[TempIndex] + " hat Tür- und Fenstersensor/en");
};
//log("Sensor " + SensorCount + " in " + room + " =" + Sensor[SensorCount] + " SensorType[y]=" + SensorType[SensorCount] + " x=" + x + " Funktion=" + Funktion);
SensorCount++;
};
};
};
};
//Struktur anlegen in js.0 um Sollwert und Summenergebniss zu speichern
//Generische Datenpunkte vorbereiten
States[DpCount] = { id: praefix + "AllWindowsClosed", initial: true, forceCreation: false, common: { read: true, write: false, name: "Sind aktuell alle Fenster geschlossen?", type: "boolean", role: "state", def: true } }; //
DpCount++;
States[DpCount] = { id: praefix + "AllDoorsClosed", initial: true, forceCreation: false, common: { read: true, write: false, name: "Sind aktuell alle Türen geschlossen?", type: "boolean", role: "state", def: true } }; //
DpCount++;
States[DpCount] = { id: praefix + "WindowsOpen", initial: 0, forceCreation: false, common: { read: true, write: false, name: "Anzahl der geöffneten Fenster", type: "number", def: 0 } };
DpCount++;
States[DpCount] = { id: praefix + "DoorsOpen", initial: 0, forceCreation: false, common: { read: true, write: false, name: "Anzahl der geöffneten Türen", type: "number", def: 0 } };
DpCount++;
States[DpCount] = { id: praefix + "WindowsTilted", initial: 0, forceCreation: false, common: { read: true, write: false, name: "Anzahl der gekippten Fenster", type: "number", def: 0 } };
DpCount++;
States[DpCount] = { id: praefix + "DoorsTilted", initial: 0, forceCreation: false, common: { read: true, write: false, name: "Anzahl der gekippten Türen", type: "number", def: 0 } };
DpCount++;
States[DpCount] = { id: praefix + "RoomsWithOpenings", initial: "", forceCreation: false, common: { read: true, write: false, name: "In welchen Räumen sind Türen/Fenster geöffnet?", type: "string", def: "" } };
DpCount++;
States[DpCount] = { id: praefix + "RoomsWithOpenDoors", initial: "", forceCreation: false, common: { read: true, write: false, name: "In welchen Räumen sind Türen geöffnet?", type: "string", def: "" } };
DpCount++;
States[DpCount] = { id: praefix + "RoomsWithTiltedDoors", initial: "", forceCreation: false, common: { read: true, write: false, name: "In welchen Räumen sind Türen gekippt?", type: "string", def: "" } };
DpCount++;
States[DpCount] = { id: praefix + "RoomsWithOpenWindows", initial: "", forceCreation: false, common: { read: true, write: false, name: "In welchen Räumen sind Fenster geöffnet?", type: "string", def: "" } };
DpCount++;
States[DpCount] = { id: praefix + "RoomsWithTiltedWindows", initial: "", forceCreation: false, common: { read: true, write: false, name: "In welchen Räumen sind Fenster gekippt?", type: "string", def: "" } };
DpCount++;
States[DpCount] = { id: praefix + "RoomsWithVentWarnings", initial: "", forceCreation: false, common: { read: true, write: false, name: "In welchen Räumen ist eine Lüftungswarnung aktiv?", type: "string", def: "" } };
DpCount++;
States[DpCount] = { id: praefix + "LastMessage", initial: "", forceCreation: false, common: { read: true, write: false, name: "Die zuletzt ausgegebene Meldung?", type: "string", def: "" } };
DpCount++;
States[DpCount] = { id: praefix + "MessageLog", initial: "", forceCreation: false, common: { read: true, write: false, name: "Liste der letzten x ausgebenen Meldungen", type: "string", def: "" } };
DpCount++;
States[DpCount] = { id: praefix + "OverviewTable", initial: "", forceCreation: false, common: { read: true, write: false, name: "Übersicht aller Räume und geöffneten Fenster", type: "string", def: "" } };
DpCount++;
States[DpCount] = { id: praefix + "MuteMode", initial: 0, forceCreation: false, common: { read: true, write: true, name: "Stummschalten?", type: "number", min: 0, max: 2, def: 0 } };
//Alle States anlegen, Main aufrufen wenn fertig
let numStates = States.length;
States.forEach(function (state) {
createState(state.id, state.initial, state.forceCreation, state.common, function () {
numStates--;
if (numStates === 0) {
if (logging) log("CreateStates fertig!");
InitialSort();
};
});
});
function InitialSort() {
let TempRoomHas = [];
let TempRoomList = [];
let AlphabeticalSortedRoomList = RoomList.join(","); //Raumliste zu kommaseparierten String wndeln
let OrderPriority;
TempRoomList = AlphabeticalSortedRoomList.split(","); //String wieder zurück zu Array wandeln
AlphabeticalSortedRoomList = TempRoomList.sort(); //Array sortieren
if (RoomSortMode == 1) { //Raumliste sortieren //alphabetisch
for (let x = 0; x < RoomList.length; x++) { //Raum Dps durchlaufen
OrderPriority = AlphabeticalSortedRoomList.indexOf(RoomList[x]);
TempRoomList[OrderPriority] = RoomList[x];
TempRoomHas[OrderPriority] = RoomHas[x];
};
RoomList = TempRoomList;
RoomHas = TempRoomHas;
}
else if (RoomSortMode == 2) {//benutzerdefiniert
for (let x = 0; x < RoomList.length; x++) { //Raum Dps durchlaufen
OrderPriority = getState(praefix + RoomList[x] + ".RoomOrderPriority").val; //benutzdefinierte Reihenfolge lesen
TempRoomList[OrderPriority] = RoomList[x]; //und an entsprechende Stelle schreiben
TempRoomHas[OrderPriority] = RoomHas[x]; //RoomHas synchron halten
};
RoomList = TempRoomList;
RoomHas = TempRoomHas;
};
//log(RoomList);
//log(TempRoomList);
//log(RoomHas);
//log(TempRoomHas);
//log(AlphabeticalSortedRoomList);
main();
}
function init() {
MessageLog = getState(praefix + "MessageLog").val;
MuteMode = getState(praefix + "MuteMode").val;
if (PresenceDp != "") Presence = getState(PresenceDp).val;
for (let x = 0; x < RoomList.length; x++) { //Messaging DPs einlesen
SendVentMsg[x] = getState(praefix + RoomList[x] + ".SendVentMsg").val;
SendDoorOpenCloseMsg[x] = getState(praefix + RoomList[x] + ".SendDoorOpenCloseMsg").val;
SendWindowOpenCloseMsg[x] = getState(praefix + RoomList[x] + ".SendWindowOpenCloseMsg").val;
SendWindowWarnMsg[x] = getState(praefix + RoomList[x] + ".SendWindowWarnMsg").val;
SendDoorWarnMsg[x] = getState(praefix + RoomList[x] + ".SendDoorWarnMsg").val;
if (logging) log("x=" + x + "=" + RoomList[x] + " SendWindowWarnMsg=" + SendWindowWarnMsg[x] + " SendDoorWarnMsg=" + SendDoorWarnMsg[x] + " SendVentMsg=" + SendVentMsg[x] + " SendWindowOpenCloseMsg=" + SendWindowOpenCloseMsg[x] + " SendDoorOpenCloseMsg=" + SendDoorOpenCloseMsg[x]);
};
for (let x = 0; x < Sensor.length; x++) { //Sensor Dps einlesen
SensorVal[x] = SimplyfyWindowStates(getState(Sensor[x]).val, x); // Wert von Sensor in Schleife einlesen
SensorOldVal[x] = "";
CheckWindow(x);
};
for (let x = 0; x < RoomList.length; x++) { //Raum Dps einlesen
RoomsWithVentWarnings[x] = "";
VentWarnTime[x] = getState(praefix + RoomList[x] + ".VentWarnTime").val; //Lüftungswarnzeiten einlesen
VentMsg[x] = ""; // Lüftungsnachricht mit Leerstring initialisieren
VentCheck(x);
};
IsInit = false;
}
function main() {
init(); //Bei Scriptstart alle Sensoren und Räume einlesen
CreateTrigger(); //Trigger erstellen
CreateRoomsWithOpenDoorsList(); //Übersichtsliste mit Räumen mit offenen Türen erstellen
CreateRoomsWithTiltedDoorsList(); //Übersichtsliste mit Räumen mit offenen Türen erstellen
CreateRoomsWithOpenWindowsList(); //Übersichtsliste mit Räumen mit offenen Fenstern erstellen
CreateRoomsWithTiltedWindowsList(); //Übersichtsliste mit Räumen mit gekippten Fenstern erstellen
CreateRoomsWithOpeningsList();//Übersichtsliste mit Räumen mit offenen Fenstern und Türen erstellen
CreateRoomsWithVentWarnings();//Übersichtsliste mit Räumen mit Lüftungswarnung erstellen
CreateOverviewTable(); //HTML Tabelle erstellen
Ticker(); //Minutenticker für Tabellenrefresh starten
}
function Meldung(msg) {
if (logging) log("Reaching Meldung, msg= " + msg + " NoMsgAtPresence= " + NoMsgAtPresence + " Presence= " + Presence);
if (NoMsgAtPresence && Presence) {
if (logging) log("Meldung blocked cause, NoMsgAtPresence= " + NoMsgAtPresence + " Presence= " + Presence);
}
else {
if (MuteMode != 1 && MuteMode != 2) {
if (UseSay) Say(msg);
if (UseAlexa) {
if (AlexaId != "") setState(AlexaInstance + ".Echo-Devices." + AlexaId + ".Commands.announcement"/*announcement*/, AlexaVolume + "; " + msg);
};
};
if (MuteMode != 2) {
if (UseEventLog) {
WriteEventLog(msg);
};
if (UseTelegram) {
sendTo("telegram.0", "send", {
text: msg
});
};
if (UsePushover) {
sendTo(PushOverInstance, "send", {
device: PushOverDevice, message: msg, title: PushOverTitle, sound: PushOverSound
});
};
if (UseMail) {
sendTo("email", {
html: msg
});
};
}
setState(praefix + "LastMessage", msg, true);
WriteMessageLog(msg);
};
}
function WriteMessageLog(msg) {
if (logging) log("Reaching WriteMessageLog, Message=" + msg);
let LogEntrys = 0; //Arrayeinträge zählen
let TempMessageLog = [];
if (MessageLog == null) { //Fehler "Cannot read property 'split' of null" abfangen
if (logging) log("MessageLog=null skiping split");
}
else {
TempMessageLog = MessageLog.split(LogEntrySeparator); //Logstring in Array wandeln (Entfernt den Separator, deswegen am Funktionsende wieder anhängen)
};
if (AutoAddTimestamp) {
LogEntrys = TempMessageLog.unshift(formatDate(new Date(), LogTimeStampFormat) + ": " + msg); //neuen Eintrag am Anfang des Array einfügen, Rückgabewert setzt Zähler
} else {
LogEntrys = TempMessageLog.unshift(msg); //neuen Eintrag am Anfang des Array einfügen, Rückgabewert setzt Zähler
};
if (LogEntrys > MaxLogEntrys) { //Wenn durchs anfügen MaxLogEntrys überschritten, einen Eintrag am Ende entfernen
TempMessageLog.splice(MaxLogEntrys - LogEntrys); //Vom Ende des Arrays benötigte Anzahl Einträge löschen. Berücksichtig auch Einstellungsänderung auf niedrigere Zahl.
LogEntrys = TempMessageLog.length;
};
// log("TempMessageLog=" + TempMessageLog + " Logentrys=" + LogEntrys);
MessageLog = TempMessageLog.join(LogEntrySeparator); //Array zu String wandeln und Separator anhängen
setState(praefix + "MessageLog", MessageLog,true); //Logstring schreiben
}
function CreateOverviewTable() { // Erzeugt tabellarische Übersicht als HTML Tabelle
let OverviewTable = "";
let TableSubString = [];
TableSubString[0] = "
![]() ![]() | Fensterstatus |
"
};
//Zusammenfassung
if (ShowSummaryTbl) {
OverviewTable += "" + RoomsWithOpenings + " |
";
};
// Details / Head
if (ShowDetailTbl) {
OverviewTable += "";
OverviewTable += "";
OverviewTable += "";
OverviewTable += " | ";
OverviewTable += " | | |
";
//Tabelle der Raumdetails
for (let x = 0; x < RoomList.length; x++) { //Alle Räume durchgehen
OverviewTable += "";
RoomStateTimeCount[x] = CalcTimeDiff("now", RoomStateTimeStamp[x]);
RoomDoorStateTimeCount[x] = CalcTimeDiff("now", RoomDoorStateTimeStamp[x]);
//log("x=" + x + " Raum = "+RoomList[x] + " RoomStateTimeCount[x] = "+CreateTimeString(RoomStateTimeCount[x]) +" RoomDoorStateTimeCount[x] = "+CreateTimeString(RoomDoorStateTimeCount[x]))
if (RoomOpenWindowCount[x] > 0 || RoomOpenDoorCount[x] > 0) { // Räume mit offenen Fenstern oder Türen
if (RoomTiltedWindowCount[x] == 0 && RoomOpenWindowCount[x] > 0 && RoomOpenDoorCount[x] == 0) { //Fenster ist offen, keines ist gekippt, Tür/en sind geschlossen
if (RoomHas[x] == 2) { //RoomHas[] 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + OpenWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowOpenImg + "'>";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorCloseImg + "'>";
} else {
OverviewTable += TableSubString[0] + OpenWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowOpenImg + "'>";
OverviewTable += TableSubString[0] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorCloseImg + "'>";
};
OverviewTable += TableSubString[5] + OpenWindowColor + ";'>";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += "";
OverviewTable += TableSubString[6] + OpenWindowColor + ";'>" + ReplaceChars(RoomList[x]) + "
";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += "Fenster geöffnet: " + CreateTimeString(RoomStateTimeCount[x]) + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += "Tür geschlossen: " + CreateTimeString(RoomDoorStateTimeCount[x]);
}
else if (RoomTiltedWindowCount[x] > 0 && RoomTiltedWindowCount[x] == RoomOpenWindowCount[x] && RoomOpenDoorCount[x] == 0) { //Fenster ist gekippt, Tür/en sind geschlossen
if (RoomHas[x] == 2) { //RoomHas[] 0=Weder Tür noch Fenster, 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowTiltedImg + "'>";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorCloseImg + "'>";
} else {
OverviewTable += TableSubString[0] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowTiltedImg + "'>";
OverviewTable += TableSubString[0] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorCloseImg + "'>";
};
OverviewTable += TableSubString[5] + TiltedWindowColor + ";'>";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += "";
OverviewTable += TableSubString[6] + TiltedWindowColor + ";'>" + ReplaceChars(RoomList[x]) + "
";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += "Fenster gekippt:" + CreateTimeString(RoomStateTimeCount[x]) + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += "Tür geschlossen:" + CreateTimeString(RoomDoorStateTimeCount[x]);
}
else if (RoomTiltedWindowCount[x] < RoomOpenWindowCount[x] && RoomOpenDoorCount[x] == 0) { // Fenster sind offen und gekippt, Tür/en sind geschlossen
if (RoomHas[x] == 2) { //RoomHas[] 0=Weder Tür noch Fenster, 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + OpenWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowOpenTiltedImg + "'>";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorCloseImg + "'>";
} else {
OverviewTable += TableSubString[0] + OpenWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowOpenTiltedImg + "'>";
OverviewTable += TableSubString[0] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorCloseImg + "'>";
};
OverviewTable += TableSubString[5] + OpenWindowColor + ";'>";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += "";
OverviewTable += TableSubString[6] + OpenWindowColor + ";'>" + ReplaceChars(RoomList[x]) + "
";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += "Fenster geöffnet/gekippt:" + CreateTimeString(RoomStateTimeCount[x]) + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += "Tür geschlossen: " + CreateTimeString(RoomDoorStateTimeCount[x]);
}
//*****************
if (RoomTiltedDoorCount[x] > 0 && RoomOpenWindowCount[x] == 0) { // Tür/en gekippt, kein Fenster ist geöffnet
if (RoomHas[x] == 2) { //RoomHas[] 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowCloseImg + "'>";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorTiltedImg + "'>";
} else {
OverviewTable += TableSubString[0] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowCloseImg + "'>";
OverviewTable += TableSubString[0] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorTiltedImg + "'>";
};
OverviewTable += TableSubString[5] + OpenDoorColor + ";'>";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += "";
OverviewTable += TableSubString[6] + OpenDoorColor + ";'>" + ReplaceChars(RoomList[x]) + "
";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += "Fenster geschlossen: " + CreateTimeString(RoomStateTimeCount[x]) + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += "Tür gekippt: " + CreateTimeString(RoomDoorStateTimeCount[x]);
}
else if (RoomOpenWindowCount[x] > 0 && RoomTiltedWindowCount[x] == 0 && RoomTiltedDoorCount[x] > 0) { //Fenster ist offen, keines ist gekippt, Tür/en sind gekippt
if (RoomHas[x] == 2) { //RoomHas[] 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + OpenWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowOpenImg + "'>";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorTiltedImg + "'>";
} else {
OverviewTable += TableSubString[0] + OpenWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowOpenImg + "'>";
OverviewTable += TableSubString[0] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorTiltedImg + "'>";
};
OverviewTable += TableSubString[5] + OpenWindowColor + ";'>";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += "";
OverviewTable += TableSubString[6] + OpenWindowColor + ";'>" + ReplaceChars(RoomList[x]) + "
";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += "Fenster geöffnet: " + CreateTimeString(RoomStateTimeCount[x]) + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += "Tür gekippt: " + CreateTimeString(RoomDoorStateTimeCount[x]);
}
else if (RoomTiltedWindowCount[x] > 0 && RoomTiltedWindowCount[x] == RoomOpenWindowCount[x] && RoomTiltedDoorCount[x] > 0) { //Fenster ist gekippt, Tür/en sind gekippt
if (RoomHas[x] == 2) { //RoomHas[] 0=Weder Tür noch Fenster, 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowTiltedImg + "'>";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorTiltedImg + "'>";
} else {
OverviewTable += TableSubString[0] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowTiltedImg + "'>";
OverviewTable += TableSubString[0] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorTiltedImg + "'>";
};
OverviewTable += TableSubString[5] + TiltedWindowColor + ";'>";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += "";
OverviewTable += TableSubString[6] + TiltedWindowColor + ";'>" + ReplaceChars(RoomList[x]) + "
";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += "Fenster gekippt: " + CreateTimeString(RoomStateTimeCount[x]) + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += "Tür gekippt: " + CreateTimeString(RoomDoorStateTimeCount[x]);
}
else if (RoomOpenWindowCount[x] > 0 && RoomTiltedWindowCount[x] < RoomOpenWindowCount[x] && RoomTiltedDoorCount[x] > 0) { // Fenster sind offen und gekippt, Tür/en sind gekippt
if (RoomHas[x] == 2) { //RoomHas[] 0=Weder Tür noch Fenster, 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + OpenWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowOpenTiltedImg + "'>";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorTiltedImg + "'>";
} else {
OverviewTable += TableSubString[0] + OpenWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowOpenTiltedImg + "'>";
OverviewTable += TableSubString[0] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorTiltedImg + "'>";
};
OverviewTable += TableSubString[5] + OpenWindowColor + ";'>";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += "";
OverviewTable += TableSubString[6] + OpenWindowColor + ";'>" + ReplaceChars(RoomList[x]) + "
";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += "Fenster geöffnet/gekippt: " + CreateTimeString(RoomStateTimeCount[x]) + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += "Tür gekippt: " + CreateTimeString(RoomDoorStateTimeCount[x]);
}
//*******************/
else if (RoomOpenDoorCount[x] > 0 && RoomOpenWindowCount[x] == 0) { // Tür/en geöffnet, kein Fenster ist geöffnet
if (RoomHas[x] == 2) { //RoomHas[] 0=Weder Tür noch Fenster, 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowCloseImg + "'>";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + OpenDoorColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorOpenImg + "'>";
} else {
OverviewTable += TableSubString[0] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowCloseImg + "'>";
OverviewTable += TableSubString[0] + OpenDoorColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorOpenImg + "'>";
};
OverviewTable += TableSubString[5] + OpenDoorColor + ";'>";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += "";
OverviewTable += TableSubString[6] + OpenDoorColor + ";'>" + ReplaceChars(RoomList[x]) + "
";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += "Fenster geschlossen: " + CreateTimeString(RoomStateTimeCount[x]) + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += "Tür geöffnet: " + CreateTimeString(RoomDoorStateTimeCount[x]);
}
else if (RoomOpenWindowCount[x] > 0 && RoomTiltedWindowCount[x] == 0 && RoomOpenDoorCount[x] > 0) { //Fenster ist offen, keines ist gekippt, Tür/en sind geöffnet
if (RoomHas[x] == 2) { //RoomHas[] 0=Weder Tür noch Fenster, 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + OpenWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowOpenImg + "'>";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + OpenDoorColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorOpenImg + "'>";
} else {
OverviewTable += TableSubString[0] + OpenWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowOpenImg + "'>";
OverviewTable += TableSubString[0] + OpenDoorColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorOpenImg + "'>";
};
OverviewTable += TableSubString[5] + OpenWindowColor + ";'>";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += "";
OverviewTable += TableSubString[6] + OpenWindowColor + ";'>" + ReplaceChars(RoomList[x]) + "
";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += "Fenster geöffnet: " + CreateTimeString(RoomStateTimeCount[x]) + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += "Tür geöffnet: " + CreateTimeString(RoomDoorStateTimeCount[x]);
}
else if (RoomTiltedWindowCount[x] > 0 && RoomTiltedWindowCount[x] == RoomOpenWindowCount[x] && RoomOpenDoorCount[x] > 0) { //Fenster ist gekippt, Tür/en sind geöffnet
if (RoomHas[x] == 2) { //RoomHas[] 0=Weder Tür noch Fenster, 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowTiltedImg + "'>";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + OpenDoorColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorOpenImg + "'>";
} else {
OverviewTable += TableSubString[0] + TiltedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowTiltedImg + "'>";
OverviewTable += TableSubString[0] + OpenDoorColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorOpenImg + "'>";
};
OverviewTable += TableSubString[5] + TiltedWindowColor + ";'>";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += "";
OverviewTable += TableSubString[6] + TiltedWindowColor + ";'>" + ReplaceChars(RoomList[x]) + "
";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += "Fenster gekippt: " + CreateTimeString(RoomStateTimeCount[x]) + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += "Tür geöffnet: " + CreateTimeString(RoomDoorStateTimeCount[x]);
}
else if (RoomOpenWindowCount[x] > 0 && RoomTiltedWindowCount[x] < RoomOpenWindowCount[x] && RoomOpenDoorCount[x] > 0) { // Fenster sind offen und gekippt, Tür/en sind geöffnet
if (RoomHas[x] == 2) { //RoomHas[] 0=Weder Tür noch Fenster, 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + OpenWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowOpenTiltedImg + "'>";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + OpenDoorColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorOpenImg + "'>";
} else {
OverviewTable += TableSubString[0] + OpenWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + WindowOpenTiltedImg + "'>";
OverviewTable += TableSubString[0] + OpenDoorColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorOpenImg + "'>";
};
OverviewTable += TableSubString[5] + OpenWindowColor + ";'>";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += "";
OverviewTable += TableSubString[6] + OpenWindowColor + ";'>" + ReplaceChars(RoomList[x]) + "
";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += "Fenster geöffnet/gekippt: " + CreateTimeString(RoomStateTimeCount[x]) + "
";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += "Tür geöffnet: " + CreateTimeString(RoomDoorStateTimeCount[x]);
}
OverviewTable += "
";
}
else { // Geschlossene Räume
if (VentMsg[x] == "") { //geschlossen + keine Lüftungswarnung
if (RoomHas[x] == 2) { //RoomHas[] 0=Weder Tür noch Fenster, 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + ClosedWindowColor + ";'>
";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorCloseImg + "'>";
} else {
OverviewTable += TableSubString[0] + ClosedWindowColor + ";'>
";
OverviewTable += TableSubString[0] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorCloseImg + "'>";
};
OverviewTable += "";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + " ";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += " | ";
if (RoomHas[x] == 2) OverviewTable += TableSubString[6] + ClosedWindowColor + ";'>" + ReplaceChars(RoomList[x]) + "
Fenster geschlossen: " + CreateTimeString(RoomStateTimeCount[x]) + "
";
if (RoomHas[x] == 1) OverviewTable += TableSubString[6] + ClosedWindowColor + ";'>" + ReplaceChars(RoomList[x]) + "
Tür geschlossen: " + CreateTimeString(RoomDoorStateTimeCount[x]);
if (RoomHas[x] == 3) OverviewTable += TableSubString[6] + ClosedWindowColor + ";'>" + ReplaceChars(RoomList[x]) + "
Fenster geschlossen: " + CreateTimeString(RoomStateTimeCount[x]) + "
Tür geschlossen: " + CreateTimeString(RoomDoorStateTimeCount[x]);
OverviewTable += "
"
}
else { //geschlossen + Lüftungswarnung
if (RoomHas[x] == 2) { //RoomHas[] 0=Weder Tür noch Fenster, 1=Tür, 2=Fenster, 3=Tür+Fenster
OverviewTable += TableSubString[3] + VentWarnColor + ";'>

";
} else if (RoomHas[x] == 1) {
OverviewTable += TableSubString[3] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorOpenImg + "'>";
} else {
OverviewTable += TableSubString[0] + VentWarnColor + ";'>

";
OverviewTable += TableSubString[0] + ClosedWindowColor + TableSubString[1] + ImgInvert + "); height: 40px;' src='" + DoorOpenImg + "'>";
};
OverviewTable += "
";
if (RoomHas[x] == 2 || RoomHas[x] == 3) OverviewTable += RoomOpenWindowCount[x] + " ";
if (RoomHas[x] == 1 || RoomHas[x] == 3) OverviewTable += RoomOpenDoorCount[x];
OverviewTable += " | ";
OverviewTable += TableSubString[6] + VentWarnColor + ";'>" + ReplaceChars(RoomList[x]) + "
Raum nicht gelüftet: " + CreateTimeString(RoomStateTimeCount[x]);
OverviewTable += "
";
};
};
};
OverviewTable += "
";
};
setState(praefix + "OverviewTable", OverviewTable, true);
}
function CalcTimeDiff(time1, time2) {
if (time1 == "now") {
time1 = new Date().getTime();
};
//if (logging) log("Reaching CalcTimeDiff, time1=" + time1 + ", time2=" + time2 + ", result= " + CreateTimeString(time1 - time2));
return (time1 - time2);
}
function Ticker() {
setInterval(function () { // Wenn
//if (logging) log("Refreshing OverviewTable")
CreateOverviewTable();
}, 60000);
}
function ReplaceChars(OrigString) {
//log(typeof OrigString)
if (typeof OrigString == "undefined") OrigString = "";
let NewString = OrigString.replace("_", " ");
NewString = NewString.replace("ae", "ä");
NewString = NewString.replace("ue", "ü");
NewString = NewString.replace("oe", "ö");
return NewString;
}
function CreateRoomsWithOpenWindowsList() { //Erzeugt Textliste mit Räumen welche geöffnete Fenster haben
if (logging) log("Reaching CreateRoomsWithOpenWindowsList");
RoomsWithOpenWindows = ""; //Liste Initialisieren
for (let x = 0; x < RoomList.length; x++) { //Alle Räume durchgehen
//RoomsWithCombinedOpenings[x] = [];
if (RoomOpenWindowCount[x] > 0) { // Nur Räume mit offenen Fenstern berücksichtigen
if (RoomOpenWindowCount[x] == 1) { //Wenn 1 Fenster offen, Singular Schreibweise
if (RoomTiltedWindowCount[x] == 1) { //Wenn das eine Fenster gekippt ist
RoomsWithOpenWindows += ReplaceChars(RoomList[x]) + " " + RoomOpenWindowCount[x] + " gekipptes Fenster" + OpenWindowListSeparator;
RoomsWithCombinedOpenings[x][0] = RoomOpenWindowCount[x] + " gekipptes Fenster";
}
else {
RoomsWithOpenWindows += ReplaceChars(RoomList[x]) + " " + RoomOpenWindowCount[x] + " offenes Fenster" + OpenWindowListSeparator;
RoomsWithCombinedOpenings[x][0] = RoomOpenWindowCount[x] + " offenes Fenster";
};
}
else { //ansonsten Plural Schreibweise
if (RoomTiltedWindowCount[x] == RoomOpenWindowCount[x]) { //Wenn gekippte Fenster = offene Fenster
RoomsWithOpenWindows += RoomTiltedWindowCount[x] + " gekippte Fenster" + OpenWindowListSeparator;
RoomsWithCombinedOpenings[x][0] = RoomOpenWindowCount[x] + " gekippte Fenster";
}
else {
RoomsWithOpenWindows += ReplaceChars(RoomList[x]) + " " + RoomOpenWindowCount[x] + " offene Fenster" + OpenWindowListSeparator;
RoomList[x][0] = RoomOpenWindowCount[x] + " offene Fenster";
RoomsWithCombinedOpenings[x][0] = RoomOpenWindowCount[x] + " offene Fenster";
if (RoomTiltedWindowCount[x] == 1) { //Wenn 1 Fenster gekippt Singular schreibweise
RoomsWithOpenWindows += " davon " + RoomTiltedWindowCount[x] + " gekipptes Fenster" + OpenWindowListSeparator;
RoomsWithCombinedOpenings[x][0] = RoomOpenWindowCount[x] + " offene Fenster," + " davon " + RoomTiltedWindowCount[x] + " gekipptes Fenster";
}
else if (RoomTiltedWindowCount[x] > 1) { //ansonsten Plural Schreibweise
RoomsWithOpenWindows += " davon " + RoomTiltedWindowCount[x] + " gekippte Fenster" + OpenWindowListSeparator;
RoomsWithCombinedOpenings[x][0] = RoomOpenWindowCount[x] + " offene Fenster," + " davon " + RoomTiltedWindowCount[x] + " gekippte Fenster";
};
};
};
} else {
RoomsWithCombinedOpenings[x][0] = "Alle Fenster sind geschlossen";
};
};
RoomsWithOpenWindows = RoomsWithOpenWindows.substr(0, RoomsWithOpenWindows.length - OpenWindowListSeparator.length); //letzten
Umbruch wieder entfernen
if (RoomsWithOpenWindows == "") {
RoomsWithOpenWindows = "Alle Fenster sind geschlossen";
};
setState(praefix + "RoomsWithOpenWindows", RoomsWithOpenWindows, true);
if (logging) log("RoomsWithOpenWindows: " + RoomsWithOpenWindows);
}
function CreateRoomsWithTiltedWindowsList() { //Erzeugt Textliste mit Räumen welche gekippte Fenster haben
if (logging) log("Reaching CreateRoomsWithTiltedWindowsList");
RoomsWithTiltedWindows = ""; //Liste Initialisieren
for (let x = 0; x < RoomList.length; x++) { //Alle Räume durchgehen
if (RoomTiltedWindowCount[x] > 0) { // Nur Räume mit gekippten Fenstern berücksichtigen
if (RoomTiltedWindowCount[x] == 1) { //Wenn 1 Fenster gekippt, Singular Schreibweise
RoomsWithTiltedWindows += ReplaceChars(RoomList[x]) + " " + RoomTiltedWindowCount[x] + " gekipptes Fenster" + OpenWindowListSeparator;
}
else { //ansonsten Plural Schreibweise
RoomsWithTiltedWindows += ReplaceChars(RoomList[x]) + " " + RoomOpenWindowCount[x] + " gekippte Fenster" + OpenWindowListSeparator;
};
};
};
RoomsWithTiltedWindows = RoomsWithTiltedWindows.substr(0, RoomsWithTiltedWindows.length - OpenWindowListSeparator.length); //letzten
Umbruch wieder entfernen
if (RoomsWithTiltedWindows == "") {
RoomsWithTiltedWindows = "Keine Fenster gekippt";
};
setState(praefix + "RoomsWithTiltedWindows", RoomsWithTiltedWindows, true);
if (logging) log("RoomsWithTiltedWindows: " + RoomsWithTiltedWindows);
}
function CreateRoomsWithOpenDoorsList() { //Erzeugt Textliste mit Räumen welche offene Türen haben
if (logging) log("Reaching CreateRoomsWithOpenDoorsList");
RoomsWithOpenDoors = ""; //Liste Initialisieren
for (let x = 0; x < RoomList.length; x++) { //Alle Räume durchgehen
//RoomsWithCombinedOpenings[x] = [];
if (RoomOpenDoorCount[x] > 0) { // Nur Räume mit offenen Türen berücksichtigen
if (RoomOpenDoorCount[x] == 1) { //Wenn 1 Tür offen, Singular Schreibweise
RoomsWithOpenDoors += ReplaceChars(RoomList[x]) + " " + RoomOpenDoorCount[x] + " offene Tür" + OpenWindowListSeparator;
RoomsWithCombinedOpenings[x][1] = RoomOpenDoorCount[x] + " offene Tür";
}
else { //ansonsten Plural Schreibweise
RoomsWithOpenDoors += ReplaceChars(RoomList[x]) + " " + RoomOpenDoorCount[x] + " offene Türen" + OpenWindowListSeparator;
RoomsWithCombinedOpenings[x][1] = RoomOpenDoorCount[x] + " offene Türen";
};
} else {
RoomsWithCombinedOpenings[x][1] = "Keine Tür/en geöffnet";
};
};
RoomsWithOpenDoors = RoomsWithOpenDoors.substr(0, RoomsWithOpenDoors.length - OpenWindowListSeparator.length); //letzten
Umbruch wieder entfernen
if (RoomsWithOpenDoors == "") {
RoomsWithOpenDoors = "Keine Tür/en geöffnet";
};
setState(praefix + "RoomsWithOpenDoors", RoomsWithOpenDoors, true);
if (logging) log("RoomsWithOpenDoors: " + RoomsWithOpenDoors);
}
function CreateRoomsWithTiltedDoorsList() { //Erzeugt Textliste mit Räumen welche gekippte Türen haben
if (logging) log("Reaching CreateRoomsWithTiltedDoorsList");
RoomsWithTiltedDoors = ""; //Liste Initialisieren
for (let x = 0; x < RoomList.length; x++) { //Alle Räume durchgehen
if (RoomTiltedDoorCount[x] > 0) { // Nur Räume mit gekippten Türen berücksichtigen
if (RoomTiltedDoorCount[x] == 1) { //Wenn 1 Tür gekippt, Singular Schreibweise
RoomsWithTiltedDoors += ReplaceChars(RoomList[x]) + " " + RoomTiltedDoorCount[x] + " gekippte Tür" + OpenWindowListSeparator;
}
else { //ansonsten Plural Schreibweise
RoomsWithTiltedDoors += ReplaceChars(RoomList[x]) + " " + RoomTiltedDoorCount[x] + " gekippte Türen" + OpenWindowListSeparator;
};
};
};
RoomsWithTiltedDoors = RoomsWithTiltedDoors.substr(0, RoomsWithTiltedDoors.length - OpenWindowListSeparator.length); //letzten
Umbruch wieder entfernen
if (RoomsWithTiltedDoors == "") {
RoomsWithTiltedDoors = "Keine Tür gekippt";
};
setState(praefix + "RoomsWithTiltedDoors", RoomsWithTiltedDoors, true);
if (logging) log("RoomsWithTiltedDoors: " + RoomsWithTiltedDoors);
}
function CreateRoomsWithOpeningsList() { //Erzeugt Textliste mit Räumen welche offene Türen und/oder Fenster haben
if (logging) log("CreateOpenRoomsList()");
RoomsWithOpenings = "";
for (let x = 0; x < RoomList.length; x++) { //Alle Räume durchgehen
if (RoomOpenWindowCount[x] == 0 && RoomOpenDoorCount[x] > 0) {
RoomsWithOpenings += ReplaceChars(RoomList[x]) + " " + RoomsWithCombinedOpenings[x][1] + OpenWindowListSeparator;
}
else if (RoomOpenWindowCount[x] > 0 && RoomOpenDoorCount[x] == 0) {
RoomsWithOpenings += ReplaceChars(RoomList[x]) + " " + RoomsWithCombinedOpenings[x][0] + OpenWindowListSeparator;
}
else if (RoomOpenWindowCount[x] > 0 && RoomOpenDoorCount[x] > 0) {
RoomsWithOpenings += ReplaceChars(RoomList[x]) + " " + RoomsWithCombinedOpenings[x].join(", ") + OpenWindowListSeparator;
}
};
setState(praefix + "RoomsWithOpenings", RoomsWithOpenings, true);
if (logging) log("RoomsWithOpenings: " + RoomsWithOpenings);
}
function CreateRoomsWithVentWarnings(x, Warning) { //Erzeugt Liste mit Räumen für die eine Lüftungswarnung besteht
let Tempstring = "";
if (logging) log("Reaching CreateRoomsWithVentWarnings");
RoomsWithVentWarnings[x] = Warning;
for (let y = 0; y < RoomsWithVentWarnings.length; y++) {
if (RoomsWithVentWarnings[y] != "")
Tempstring += RoomList[y] + " nicht gelüftet seit: " + RoomsWithVentWarnings[y] + OpenWindowListSeparator;
};
Tempstring = Tempstring.substr(0, Tempstring.length - OpenWindowListSeparator.length);
setState(praefix + "RoomsWithVentWarnings", Tempstring, true);
}
function VentCheck(x) { //Überprüft wie lange Räume geschlossen sind und gibt Lüftungswarnung aus
if (logging) log("Reaching VentCheck x=" + x + " Init=" + IsInit + " VentwarnTime[x]=" + VentWarnTime[x] + " RoomStateTimeStamp[x]=" + RoomStateTimeStamp[x]);
if (RoomOpenWindowCount[x] == 0 && VentWarnTime[x] != 0) { //VentTimeout starten wenn alle Fenster im Raum geschlossen und Warnzeit nicht 0 (= deaktiviert)
if (logging) log("Starting VentInterval for Room " + RoomList[x] + " Time set to: " + VentWarnTime[x] + " days");
if (IsInit) { //Bei Skriptstart
if (CalcTimeDiff("now", RoomStateTimeStamp[x]) >= getDateObject(VentWarnTime[x] * 24 * 60 * 60 * 1000).getTime()) { //Wenn Ventwarnzeit bei Skriptstart schon überschritten, sofortige Meldung
VentMsg[x] = CreateTimeString(RoomStateTimeCount[x]);
CreateRoomsWithVentWarnings(x, VentMsg[x]);
if (SendVentMsg[x]) Meldung(ReplaceChars(RoomList[x]) + " nicht gelüftet " + VentMsg[x]);
} else { //Wenn Ventwarnzeit bei Skriptstart noch nicht überschritten, Restzeit berechnen und einmaligen Timeout starten welcher bei Ablauf den regulären Interval startet
if (logging) log("Remaining Vent Warn DiffTime at startup= " + CreateTimeString(CalcTimeDiff(VentWarnTime[x] * 24 * 60 * 60 * 1000, RoomStateTimeCount[x])))
VentMsgHandler[x] = setTimeout(function () {
RoomStateTimeCount[x] = CalcTimeDiff("now", RoomStateTimeStamp[x]); //RoomstateTimeCount aktualisieren um exakten Wert bei Ausgabe zu haben und 23 Stunden 59 Minuten Meldungen zu vermeiden
VentMsg[x] = CreateTimeString(RoomStateTimeCount[x]);
CreateRoomsWithVentWarnings(x, VentMsg[x]);
if (SendVentMsg[x]) {
Meldung(ReplaceChars(RoomList[x]) + " nicht gelüftet " + VentMsg[x]);
CreateOverviewTable();
};
if (logging) log("Init Vent Timeout exceeded now calling regular Interval for x=" + x);
VentCheck(x);
}, CalcTimeDiff(VentWarnTime[x] * 24 * 60 * 60 * 1000, RoomStateTimeCount[x]));
};
} else { //Normalbetrieb, kein Init
VentMsgHandler[x] = setInterval(function () { // Neuen Timeout setzen, volle Warnzeit
RoomStateTimeCount[x] = CalcTimeDiff("now", RoomStateTimeStamp[x]); //RoomstateTimeCount aktualisieren um exakten Wert bei Ausgabe zu haben und 23 Stunden 59 Minuten Meldungen zu vermeiden
VentMsg[x] = CreateTimeString(RoomStateTimeCount[x]); //Watch!!
CreateRoomsWithVentWarnings(x, VentMsg[x])
if (SendVentMsg[x]) {
Meldung(ReplaceChars(RoomList[x]) + " nicht gelüftet " + VentMsg[x]);
CreateOverviewTable();
};
}, VentWarnTime[x] * 24 * 60 * 60 * 1000);
};
if (logging) log("VentMsg=" + VentMsg[x]);
}
else if (RoomOpenWindowCount[x] != 0 || VentWarnTime[x] == 0) {
if (logging) log("Room " + x + " = " + RoomList[x] + " is open or disabled, no vent warning set");
CreateRoomsWithVentWarnings(x, "");
ClearVentTime(x);
VentMsg[x] = "";
};
}
function GetRoom(x) { // Liefert den Raum von Sensor x
if (logging) log("Reaching GetRoom x=" + x)
let room = getObject(Sensor[x], 'rooms').enumNames[0];
if (typeof room == "undefined") {
log("Kein Raum definiert bei Sensor " + Sensor[x], 'error');
return "Kein Raum definiert";
};
if (typeof room == 'object') room = room.de;
return room;
}
function CheckWindow(x) { //Für einzelnes Fenster/Tür. Via Trigger angesteuert. Eigentliche Primärauswertefunktion des Skriptes
let TempRoom = GetRoom(x); //Raum des aktuellen Sensors bestimmen
let TempRoomIndex = RoomList.indexOf(TempRoom); // Raumlistenindex für aktuellen Raum bestimmen
if (logging) log("reaching CheckWindow, SensorVal[" + x + "]=" + SensorVal[x] + " SensorOldVal=" + SensorOldVal[x] + " TempRoom=" + TempRoom + " SensorType[x]=" + SensorType[x] + " TempRoomIndex=" + TempRoomIndex)
if (((SensorVal[x] == "open") && (SensorOldVal[x] == "closed" || SensorOldVal[x] == "" || SensorOldVal[x] != "tilted")) || ((SensorVal[x] == "tilted") && (SensorOldVal[x] == "closed" || SensorOldVal[x] == "" || SensorOldVal[x] != "open"))) { //Fenster war geschlossen und wurde geöffnet oder gekippt - Wechsel von open auf tilted nicht berücksichtigt!!!
if (SensorType[x] == "Window") {
if (RoomOpenWindowCount[TempRoomIndex] == 0) setState(praefix + TempRoom + ".WindowIsOpen", true, true);
if (RoomOpenWindowCount[TempRoomIndex] == 0) setState(praefix + TempRoom + ".RoomIsOpen", true, true);
OpenWindowCount++; //Gesamtfensterzähler erhöhen
RoomOpenWindowCount[TempRoomIndex]++; //Raumfensterzähler erhöhen
if (logging) log("RoomOpenWindowCount für " + TempRoom + "=" + RoomOpenWindowCount[TempRoomIndex]);
setState(praefix + TempRoom + ".RoomOpenWindowCount", RoomOpenWindowCount[TempRoomIndex], true);
if (!IsInit) {
if (RoomOpenWindowCount[TempRoomIndex] == 1) {
RoomStateTimeStamp[TempRoomIndex] = new Date().getTime(); //Bei Erstöffnung Zeitstempel für Raum auf jetzt setzen
};
if (SensorVal[x] == "open") {
if (logging) log(TempRoom + " Fenster geöffnet");
if (SendWindowOpenCloseMsg[TempRoomIndex]) Meldung(ReplaceChars(TempRoom) + " Fenster geöffnet!");
if (UseEventLog) WriteEventLog(ReplaceChars(TempRoom) + " Fenster geöffnet!");
}
else if (SensorVal[x] == "tilted") {
if (logging) log(TempRoom + " Fenster gekippt");
if (SendWindowOpenCloseMsg[TempRoomIndex]) Meldung(ReplaceChars(TempRoom) + " Fenster gekippt!");
if (UseEventLog) WriteEventLog(ReplaceChars(TempRoom) + " Fenster gekippt!");
};
};
if (RoomOpenWindowCount[TempRoomIndex] == 1) {
if (logging) log("SendWindowWarnMsg=" + SendWindowWarnMsg[TempRoomIndex] + " TempRoomIndex=" + TempRoomIndex)
WindowWarnRuntime[TempRoomIndex] = 0;
if (SendWindowWarnMsg[TempRoomIndex]) {
if (logging) log("Setting Interval to Room:" + TempRoom);
OpenWindowMsgHandler[TempRoomIndex] = setInterval(function () {// Interval starten und Dauer bei Ansage aufaddieren
WindowWarnRuntime[TempRoomIndex] = WindowWarnRuntime[TempRoomIndex] + TimeToWindowMsg;
if (RoomWindowMsgCount[TempRoomIndex] <= MaxMessages - 1) Meldung(ReplaceChars(TempRoom) + "fenster seit " + CreateTimeString(CalcTimeDiff("now", RoomStateTimeStamp[TempRoomIndex])) + " geöffnet!");
RoomWindowMsgCount[TempRoomIndex]++;
}, TimeToWindowMsg);
};
};
} else if (SensorType[x] == "Door") {
if (RoomOpenDoorCount[TempRoomIndex] == 0) setState(praefix + TempRoom + ".DoorIsOpen", true, true);
if (RoomOpenDoorCount[TempRoomIndex] == 0) setState(praefix + TempRoom + ".RoomIsOpen", true, true);
OpenDoorCount++; //Gesamttürzähler erhöhen
RoomOpenDoorCount[TempRoomIndex]++; //Raumtürzähler erhöhen
if (logging) log("RoomOpenDoorCount für " + TempRoom + "=" + RoomOpenDoorCount[TempRoomIndex]);
setState(praefix + TempRoom + ".RoomOpenDoorCount", RoomOpenDoorCount[TempRoomIndex], true);
if (!IsInit) {
if (RoomOpenDoorCount[TempRoomIndex] == 1) {
RoomDoorStateTimeStamp[TempRoomIndex] = new Date().getTime(); //Bei Erstöffnung Zeitstempel für Raum auf jetzt setzen
};
if (SensorVal[x] == "open") {
if (logging) log(TempRoom + " Tür geöffnet");
if (SendDoorOpenCloseMsg[TempRoomIndex]) Meldung(ReplaceChars(TempRoom) + " Tür geöffnet!");
if (UseEventLog) WriteEventLog(ReplaceChars(TempRoom) + " Tür geöffnet!");
}
else if (SensorVal[x] == "tilted") {
if (logging) log(TempRoom + " Tür gekippt");
if (SendDoorOpenCloseMsg[TempRoomIndex]) Meldung(ReplaceChars(TempRoom) + " Tür gekippt!");
if (UseEventLog) WriteEventLog(ReplaceChars(TempRoom) + " Tür gekippt!");
};
};
if (RoomOpenDoorCount[TempRoomIndex] == 1) {
if (logging) log("SendDoorWarnMsg=" + SendDoorWarnMsg[TempRoomIndex] + " TempRoomIndex=" + TempRoomIndex)
DoorWarnRuntime[TempRoomIndex] = 0;
if (SendDoorWarnMsg[TempRoomIndex]) {
if (logging) log("Setting Interval to Room:" + TempRoom);
OpenDoorMsgHandler[TempRoomIndex] = setInterval(function () {// Interval starten und Dauer bei Ansage aufaddieren
DoorWarnRuntime[TempRoomIndex] = DoorWarnRuntime[TempRoomIndex] + TimeToDoorMsg;
if (RoomDoorMsgCount[TempRoomIndex] <= MaxMessages - 1) Meldung(ReplaceChars(TempRoom) + "tür seit " + CreateTimeString(CalcTimeDiff("now", RoomDoorStateTimeStamp[TempRoomIndex])) + " geöffnet!");
RoomDoorMsgCount[TempRoomIndex]++;
}, TimeToDoorMsg);
};
};
}
}
else if (SensorVal[x] == "closed") {
if (SensorType[x] == "Window") {
if (!IsInit) { // Wenn nicht in Initialisierungsphase (Skriptstart)
if (OpenWindowCount > 0) OpenWindowCount--;
if (RoomOpenWindowCount[TempRoomIndex] > 0) RoomOpenWindowCount[TempRoomIndex]--;
if (RoomOpenWindowCount[TempRoomIndex] == 0) { // Wenn letztes Fenster geschlossen
RoomStateTimeStamp[TempRoomIndex] = new Date().getTime(); //Bei schliessen Zeitstempel für Raum setzen
if (logging) log(TempRoom + " Fenster geschlossen.");
if (SendWindowOpenCloseMsg[TempRoomIndex]) Meldung(ReplaceChars(TempRoom) + " Fenster geschlossen!");
if (UseEventLog) WriteEventLog(ReplaceChars(TempRoom) + " Fenster geschlossen!");
};
};
setState(praefix + TempRoom + ".RoomOpenWindowCount", RoomOpenWindowCount[TempRoomIndex], true);
}
else if (SensorType[x] == "Door") {
if (!IsInit) { // Wenn nicht in Initialisierungsphase (Skriptstart)
if (OpenDoorCount > 0) OpenDoorCount--;
if (RoomOpenDoorCount[TempRoomIndex] > 0) RoomOpenDoorCount[TempRoomIndex]--;
if (RoomOpenDoorCount[TempRoomIndex] == 0) { // Wenn letzte Tür geschlossen
RoomDoorStateTimeStamp[TempRoomIndex] = new Date().getTime(); //Bei schliessen Zeitstempel für Raum setzen
if (logging) log(TempRoom + " Tür geschlossen.");
if (SendDoorOpenCloseMsg[TempRoomIndex]) Meldung(ReplaceChars(TempRoom) + " Tür geschlossen!");
if (UseEventLog) WriteEventLog(ReplaceChars(TempRoom) + " Tür geschlossen!");
};
};
if (logging) log("RoomOpenDoorCount[TempRoomIndex]=" + RoomOpenDoorCount[TempRoomIndex] + " TempRoom=" + TempRoom + " TempRoomIndex=" + TempRoomIndex)
setState(praefix + TempRoom + ".RoomOpenDoorCount", RoomOpenDoorCount[TempRoomIndex], true);
};
if (RoomOpenWindowCount[TempRoomIndex] == 0) { //Wenn alle Fenster im Raum geschlossen, Dp aktualisieren und Intervall/Timeout löschen
setState(praefix + TempRoom + ".WindowIsOpen", false, true);
ClearWindowWarnTime(TempRoomIndex);
};
if (RoomOpenDoorCount[TempRoomIndex] == 0) { //Wenn alle Türen im Raum geschlossen, Dp aktualisieren
setState(praefix + TempRoom + ".DoorIsOpen", false, true);
ClearDoorWarnTime(TempRoomIndex);
};
if (RoomOpenDoorCount[TempRoomIndex] == 0 && RoomOpenWindowCount[TempRoomIndex] == 0) { //Wenn alle Türen und Fenster im Raum geschlossen, Dp aktualisieren
setState(praefix + TempRoom + ".RoomIsOpen", false, true);
};
};
//*************Bereich gekippte Fenster */
if (SensorType[x] == "Window") {
if (SensorVal[x] == "tilted") {
if (logging) log("Reaching tilted+ in checkWindow");
TiltedWindowCount++; //Gekippte Fenster Zähler erhöhen
RoomTiltedWindowCount[TempRoomIndex]++;
setState(praefix + TempRoom + ".RoomTiltedWindowCount", RoomTiltedWindowCount[TempRoomIndex], true);
if (logging) log("TiltedWindowCount=" + TiltedWindowCount + " RoomTiltedWindowCount=" + RoomTiltedWindowCount[TempRoomIndex] + " TempRoomIndex=" + TempRoomIndex)
}
else if ((SensorVal[x] != "tilted" && SensorOldVal[x] == "tilted") && IsInit == false) { //Bei Wechsel von gekippt auf offen oder geschlossen und keine Initphase
if (logging) log("Reaching tilted- in checkWindow");
TiltedWindowCount--; //Gekippte Fenster Zähler erniedrigen
RoomTiltedWindowCount[TempRoomIndex]--;
if (TiltedWindowCount < 0) TiltedWindowCount = 0;
if (RoomTiltedWindowCount[TempRoomIndex] < 0) RoomTiltedWindowCount[TempRoomIndex] = 0;
setState(praefix + TempRoom + ".RoomTiltedWindowCount", RoomTiltedWindowCount[TempRoomIndex], true);
if (logging) log("TiltedWindowCount=" + TiltedWindowCount + " RoomTiltedWindowCount=" + RoomTiltedWindowCount[TempRoomIndex] + " TempRoomIndex=" + TempRoomIndex)
};
if (IsInit && RoomTiltedWindowCount[TempRoomIndex] == 0) {
setState(praefix + TempRoom + ".RoomTiltedWindowCount", RoomTiltedWindowCount[TempRoomIndex], true);
};
if (RoomOpenWindowCount[TempRoomIndex] == 0 && RoomOpenDoorCount[TempRoomIndex] == 0) {
setState(praefix + TempRoom + ".RoomIsOpen", false, true);
}
else {
setState(praefix + TempRoom + ".RoomIsOpen", true, true);
};
}
/***************Ende Bereich gekippte Fenster Beginn Bereich gekippte Türen*/
if (SensorType[x] == "Door") {
if (SensorVal[x] == "tilted") {
if (logging) log("Reaching tilted+ in checkWindow");
TiltedDoorCount++; //Gekippte Türen Zähler erhöhen
RoomTiltedDoorCount[TempRoomIndex]++;
setState(praefix + TempRoom + ".RoomTiltedDoorCount", RoomTiltedDoorCount[TempRoomIndex], true);
if (logging) log("TiltedDoorCount=" + TiltedDoorCount + " RoomTiltedDoorCount=" + RoomTiltedDoorCount[TempRoomIndex] + " TempRoomIndex=" + TempRoomIndex)
}
else if ((SensorVal[x] != "tilted" && SensorOldVal[x] == "tilted") && IsInit == false) { //Bei Wechsel von gekippt auf offen oder geschlossen und keine Initphase
if (logging) log("Reaching tilted- in checkDoor");
TiltedDoorCount--; //Gekippte Türen Zähler erniedrigen
RoomTiltedDoorCount[TempRoomIndex]--;
if (TiltedDoorCount < 0) TiltedDoorCount = 0;
if (RoomTiltedDoorCount[x] < 0) RoomTiltedDoorCount[x] = 0;
setState(praefix + TempRoom + ".RoomTiltedDoorCount", RoomTiltedDoorCount[TempRoomIndex], true);
if (logging) log("TiltedDoorCount=" + TiltedDoorCount + " RoomTiltedDoorCount=" + RoomTiltedDoorCount[TempRoomIndex] + " TempRoomIndex=" + TempRoomIndex)
};
if (IsInit && RoomTiltedDoorCount[TempRoomIndex] == 0) {
setState(praefix + TempRoom + ".RoomTiltedDoorCount", RoomTiltedDoorCount[TempRoomIndex], true);
};
if (RoomOpenWindowCount[TempRoomIndex] == 0 && RoomOpenDoorCount[TempRoomIndex] == 0) {
setState(praefix + TempRoom + ".RoomIsOpen", false, true);
}
else {
setState(praefix + TempRoom + ".RoomIsOpen", true, true);
};
}
/***************Ende Bereich gekippte Türen*/
RoomOpenCount[TempRoomIndex] = RoomOpenDoorCount[TempRoomIndex] + RoomOpenWindowCount[TempRoomIndex];
setState(praefix + TempRoom + ".RoomOpenCount", RoomOpenCount[TempRoomIndex], true);
if (OpenWindowCount == 0) { //Wenn kein Fenster mehr offen Datenpunkte aktualisieren
setState(praefix + "WindowsOpen", 0, true);
setState(praefix + "WindowsTilted", 0, true);
setState(praefix + "AllWindowsClosed", true, true);
if (logging) log("Alle Fenster geschlossen.");
}
else if (OpenWindowCount != 0) { //ansonsten ebenfalls Datenpunkte (mit anderen Werten) aktualisieren
setState(praefix + "WindowsOpen", OpenWindowCount, true);
setState(praefix + "WindowsTilted", TiltedWindowCount, true);
setState(praefix + "AllWindowsClosed", false, true);
};
if (logging) log("Offene Fenster gesamt= " + OpenWindowCount);
if (OpenDoorCount == 0) { //Wenn keine Tür mehr offen Datenpunkte aktualisieren
setState(praefix + "DoorsOpen", 0, true);
setState(praefix + "DoorsTilted", 0, true);
setState(praefix + "AllDoorsClosed", true, true);
if (logging) log("Alle Türen geschlossen.");
}
else { //ansonsten ebenfalls Datenpunkte (mit anderen Werten) aktualisieren
setState(praefix + "DoorsOpen", OpenDoorCount, true);
setState(praefix + "DoorsTilted", TiltedDoorCount, true);
setState(praefix + "AllDoorsClosed", false, true);
};
if (logging) log("Offene Türen gesamt= " + OpenDoorCount);
if (IsInit) { // Wenn in Initialisierungsphase (Skriptstart)
RoomStateTimeStamp[TempRoomIndex] = getState(praefix + RoomList[TempRoomIndex] + ".WindowIsOpen").lc;
RoomDoorStateTimeStamp[TempRoomIndex] = getState(praefix + RoomList[TempRoomIndex] + ".DoorIsOpen").lc;
}
else {
if (SensorType[x] == "Window") VentCheck(TempRoomIndex);
if (logging) log("RoomStateTimeStamp at checkWindow= " + RoomStateTimeStamp[TempRoomIndex] + " ms =" + formatDate(RoomStateTimeStamp[TempRoomIndex], LogTimeStampFormat));
};
RoomStateTimeCount[TempRoomIndex] = CalcTimeDiff("now", RoomStateTimeStamp[TempRoomIndex]);
RoomDoorStateTimeCount[TempRoomIndex] = CalcTimeDiff("now", RoomDoorStateTimeStamp[TempRoomIndex]);
}
function CheckForHmShit(val, x) {
if (logging) log("Reaching CheckForHmShit val=" + val + " typof val=" + typeof (val) + " x=" + x + " Sensor[x]=" + Sensor[x]);
if (Sensor[x].indexOf("hm-rpc.") != -1) { //Prüfen ob Sensor= HM Sensor
if (getObject(Sensor[x]).common.states) { //Prüfen ob Wertelistentext vorhanden
if (logging) log(Sensor[x] + " hat Zustandstext " + getObject(Sensor[x]).common.states[val] + ", Wert= " + val + " Wert wird durch Zustandstext ersetzt");
return getObject(Sensor[x]).common.states[val]; //Wert durch Zustandstext ersetzen um HM Wertekuddelmuddel bei HM Sensoren zu kompensieren und in Kleinbuchstaben wandeln
}
else {
// if (logging) log(Sensor[x] + "(HM) hat keinen Zustandstext, Wert wird beibehalten")
return val;
};
}
else {
// if (logging) log(Sensor[x] + " ist non HM, Wert wird beibehalten")
return val;
};
}
function SimplyfyWindowStates(val, x) { //Die verschiedenen Gerätestates zu open, close oder tilted vereinfachen
val = String(val).toLowerCase();
val = CheckForHmShit(val, x).toLowerCase();
if (WindowIsOpenWhen.indexOf(val) != -1) { // Suche in Fensteroffenarray, wenn gefunden, Status auf open setzen
return "open";
}
else if (WindowIsClosedWhen.indexOf(val) != -1) { // Suche in Fenstergeschlossenarray, wenn gefunden, Status auf closed setzen
return "closed";
}
else if (WindowIsTiltedWhen.indexOf(val) != -1) { // Suche in Fenstergekipptarray, wenn gefunden, Status auf tilted setzen
return "tilted";
};
if (val != "open" && val != "closed" && val != "tilted") { // Suche in Fensteroffenarray und Fenstergeschlossenarray, wenn nirgends gefunden, Status auf closed setzen und Logwarnung ausgeben
log("Unknown Windowstate " + SensorVal[x] + " detected at " + Sensor[x] + ", please check your configuration", "warn");
return "unknown";
};
}
function CreateTimeString(mstime) {
let TimeString;
mstime += 1000; //Eine Sekunde erhöhen um 59Min, 59Sek Meldungen zu vermeiden
let days = Math.floor(mstime / (1000 * 60 * 60 * 24));
mstime = mstime % (1000 * 60 * 60 * 24);
let hours = Math.floor(mstime / (1000 * 60 * 60));
mstime = mstime % (1000 * 60 * 60);
let mins = Math.floor(mstime / (1000 * 60));
mstime = mstime % (1000 * 60);
let seks = Math.floor(mstime / 1000);
if (days > 0) {
if (days == 1) { //Singular
TimeString = days + " Tag ";
} else { //Plural
TimeString = days + " Tage ";
};
} else {
TimeString = "";
};
if (hours > 0) {
if (hours == 1) { //Singular
TimeString = TimeString + hours + " Std. ";
} else { //Plural
TimeString = TimeString + hours + " Std. ";
};
} else {
TimeString = TimeString + "";
};
if (mins > 0) {
if (mins == 1) { //Singular
TimeString = TimeString + mins + " Min. ";
} else { //Plural
TimeString = TimeString + mins + " Min. ";
};
} else {
TimeString = TimeString + "";
};
/*
if (seks > 0) {
if (seks == 1) { //Singular
TimeString = TimeString + seks + " Sekunde ";
} else { //Plural
TimeString = TimeString + seks + " Sekunden ";
};
} else {
TimeString = TimeString + "";
};
//if (logging) log(TimeString);
*/
if (TimeString == "") TimeString = "gerade eben"
//if (logging) log("days=" + days + ", hours=" + hours + ", mins=" + mins + ", seks=" + seks + ", Timestring=" + TimeString)
return TimeString.trim();
}
function ClearVentTime(x) {
if (typeof (VentMsgHandler[x]) == "object") { //Wenn ein Interval oder Timeout gesetzt ist, löschen
if (logging) log("Clearing Interval for " + x)
clearInterval(VentMsgHandler[x]);
clearTimeout(VentMsgHandler[x]);
};
}
function ClearWindowWarnTime(x) {
if (logging) log("reaching ClearWindowWarnTime - [x] = " + [x]);
if (typeof (OpenWindowMsgHandler[x]) == "object") { //Wenn ein Interval gesetzt ist, löschen
if (logging) log("Clearing Interval for " + x)
clearInterval(OpenWindowMsgHandler[x]); //
RoomWindowMsgCount[x] = 0; //Nachrichtenzähler wieder resetten
};
}
function ClearDoorWarnTime(x) {
if (logging) log("reaching ClearDoorWarnTime - [x] = " + [x]);
if (typeof (OpenDoorMsgHandler[x]) == "object") { //Wenn ein Interval gesetzt ist, löschen
if (logging) log("Clearing Door Interval for " + x)
clearInterval(OpenDoorMsgHandler[x]); //
RoomDoorMsgCount[x] = 0; //Nachrichtenzähler wieder resetten
};
}
function CreateTrigger() {
//Trigger für Sensoren erzeugen
let IgnoreTime;
for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
IgnoreInProcess[x] = true;
on(Sensor[x], function (dp) { //Trigger in Schleife erstellen
if (SensorType[x] == "Window") {
IgnoreTime = WindowIgnoreTime
} else if (SensorType[x] == "Door") {
IgnoreTime = DoorIgnoreTime
};
if (logging) log("Trigger= " + x + " Wert= " + dp.state.val + " Alter Wert= " + dp.oldState.val + " dp.channelId=" + dp.channelId + " dp.channelName=" + dp.channelName);
//if (logging) log("Trigger= " + x + " Wert= " + dp.state.val + " Alter Wert= " + dp.oldState.val);
if (IgnoreInProcess[x] == true) { //Bei erster Triggerung aktuellen Sensorwert merken und Timeout starten
// log("Oldstate=" + dp.oldState.val)
IgnoreValue[x] = SimplyfyWindowStates(dp.oldState.val, x);
IgnoreInProcess[x] = false;
if (logging) log("Activating Ignore Timeout for " + x + ", Value to ignore=" + IgnoreValue[x]);
setTimeout(function () {
if (logging) log("InTimeout - Trigger= " + x + " Wert= " + dp.state.val + " Alter Wert= " + dp.oldState.val);
if (SimplyfyWindowStates(getState(Sensor[x]).val, x) != IgnoreValue[x]) { //Nachdem Timeout abgelaufen, vergleichen ob gemerkter Wert mit aktuellem Wert übereinstimmt, wenn nicht, Aktionen starten
if (logging) log("Ignore Timeout for " + x + " exceeded, Value change happend, starting Functions");
SensorVal[x] = SimplyfyWindowStates(getState(Sensor[x]).val, x); // Alles in String und Kleinschreibweise wandeln
SensorOldVal[x] = IgnoreValue[x]; // Alles in String und Kleinschreibweise wandeln
CheckWindow(x);
CreateRoomsWithOpenWindowsList();
CreateRoomsWithTiltedWindowsList();
CreateRoomsWithOpenDoorsList();
CreateRoomsWithTiltedDoorsList();
CreateRoomsWithOpeningsList();
CreateOverviewTable();
} else {
if (logging) log("Ignore Timeout for " + x + " exceeded, no Value change, nothing to do. Actual Value=" + SimplyfyWindowStates(getState(Sensor[x]).val, x) + " remembered Value=" + IgnoreValue[x]);
};
IgnoreInProcess[x] = true;
}, IgnoreTime);
};
});
};
//Trigger für Räume erzeugen
for (let x = 0; x < RoomList.length; x++) { //Alle Räume durchlaufen
on(praefix + RoomList[x] + ".VentWarnTime", function (dp) { //Trigger für VentwarnTime Einstellfeld in Schleife erstellen
if (logging) log("Raum= " + RoomList[x] + " VentWarnTime= " + dp.state.val + " Alter Wert= " + dp.oldState.val);
VentWarnTime[x] = dp.state.val;
IsInit = true
ClearVentTime(x);
VentMsg[x] = "";
VentCheck(x);
IsInit = false
CreateOverviewTable();
});
on(praefix + RoomList[x] + ".SendVentMsg", function (dp) { //Trigger für SendMsgDps erzeugen
SendVentMsg[x] = dp.state.val;
});
on(praefix + RoomList[x] + ".SendWindowOpenCloseMsg", function (dp) { //Trigger
SendWindowOpenCloseMsg[x] = dp.state.val;
});
on(praefix + RoomList[x] + ".SendDoorOpenCloseMsg", function (dp) { //Trigger
SendDoorOpenCloseMsg[x] = dp.state.val;
});
on(praefix + RoomList[x] + ".SendWindowWarnMsg", function (dp) { //Trigger
SendWindowWarnMsg[x] = dp.state.val;
ClearWindowWarnTime(x);
});
on(praefix + RoomList[x] + ".SendDoorWarnMsg", function (dp) { //Trigger
SendDoorWarnMsg[x] = dp.state.val;
ClearWindowWarnTime(x);
});
};
on(praefix + "MuteMode", function (dp) { //Trigger für MuteMode erzeugen
MuteMode = dp.state.val;
});
if (PresenceDp != "") { //Trigger fürPresenceDp erzeugen wenn vorhanden
if (logging) log("PresenceDp available, created Trigger for Presence")
on(PresenceDp, function (dp) { //Trigger für Presence erzeugen
Presence = dp.state.val;
if (logging) log("Presence changed to " + Presence)
});
};
onStop(function () { //Bei Scriptende alle Timer löschen
for (let x = 0; x < RoomList.length; x++) {
ClearVentTime(x);
ClearWindowWarnTime(x)
};
}, 100);
}