//..........Anwesenheitssimulation AWS //..........Initiales Datum: 28.12.2015 //..........Autor: Looxer01 //..........Forum ioBroker //..........http://forum.iobroker.com/posting.php?mode=post&f=21&sid=b3b2a31dae55081fedaf0ad9c8d74acd // //..........Änderungshistorie //..........Version 0.10 Initial 28.12.2015 //..........Version 0.11 29.12.2015 Einstellungen um Astrozeiten erweitert (noch ohne Funktion) //.........,Version 0.12 29.12.2015 EVENT Deaktivierung von AWS hinzugefügt: Schreiben Log und loeschen Schedules //...............................................Aktivierung von AWS hihzugüfügt: Schreiben Log bei Aktivierung //..........Version 0.13 29.12.2015 das Schreiben des externen Logs optional gemacht - unter Einstellungen auswaehlbar //..........Version 0.20 29.12.2015 Astrozeit Funktion hinzugefügt. Astrozeit wird je IDGruppe auf true/false gesetzt und overruled die variablen zeit1von,zeit2von,zeit3von,zeit4von,zeit5von //..........Version 0.30 29.12.2015 Umarbeitung zur Verkürzung des Scripts //..........Version 0.31 30.12.2015 Fehlerbeseitigung in IDGruppen3 und 4 - einige Code Hygiene Massnahmen //..................................Umbenennung der IDGruppen mit führend "ID" / Startverzögerungseinstellungen hinzugefügt //..........Version 0.32 30.12.2015 umgestellt auf setStateDelayed / Startverzögerungsfunktion hinzugefügt. //..........Version 0.33 31.12.2015 Fehler mit EVAL Funktion gefixt / Fehler mit Startverzoegerung und Einschaltzeiten gefixt //..................................Funktion Anzahl von Geraete Teilnehmer zur Geraete ID bestimmung hinzugefügt //..........Version 0.40 01.01.2016 Log-Pfad variablel gemacht // Log-File Format umgearbeitet und Headerline hinzugefügt fuer externes Log. Internes Log ueberarbeitet //..........Version 0.41 02.01.2016 Funktionen von Baetz zum TimeInRange Check hinzugefuegt. Keine Globale Funktion mehr notwendig. -- Kommentarte ueberarbeitet //..........Version 0.42 02.01.2015 Herkunftsnachweis für IsTimeInRange Funktion hinzugefuegt //..................................Fehler zur zufaelligen Geraete Findung behoben. Das letzte Geraet wurde nie ausgewaehlt // Fehler im log "Gearaet wurde nicht eingeschaltet wurde gelogged auch wenn es eingeschaltet wurde" //..........Version 0.43 03.01.2015 Wenn AWS auf inaktiv gesetzt wird, dann werden alle teilnehmenden Geraete ausgeschaltet - Dokumentation der Variablen / variablen deklaration nachgeholt fuer zwei Faelle //..........Version 0.44 04.01.2015 Addieren der Einschaltverzoegerung zur Ausschaltzeit fuer die Ausschaltzeitberechnung // Fixed Fehler doppelte Schaltung fuer STATE geraete //..........Version 0.45 04.01.2015 weiterer Fehler zur Berechnung der Ausschaltzeit korrigiert //..........Version 0.50 04.01.2015 Beseitigung unnötiges Coding // Ueberpruefung ob Geraet existiert hinzugefuegt - LogMeldung falls nicht hinzugefuegt. - kein Javascript restart mehr, wenn geraet nicht existiert //..........Version 0.60 04.01.2015 Ausschalten der Teilnehmer bei Deaktivierung optimiert. Ausschaltung optional gemacht / Astrozeit ueberarbeitet //..................................Astrozeit auch fuer die bis Zeit hinzugefuegt. Damit lassen sich Schaltungen bis zum Sonnenaufgang umsetzen / weitere Codeoptimierungen //..........Version 0.61 05.01.2015 Beim Ausschalten Verzoegerung zwischen Schaltvorgange eingebaut / Codeiptimierung bei den Gruppen Schedules / Fehler bei der GrpZufAnz und StartDelay beseitigt fuer Gruppen 2-5 //..........Version 0.65 06.01.2015 Reaktion bei bereits eigneschalteten Lampen variabel gemacht / Codeoptimierungen / ID fuer AWS-Aktiv ist jetzt variabel //..........Version 0.70 26.01.2015 SetStateDelayed ist jetzt in javascript gefixt ab JS version 1.1.2 - Das Loeschen von Ein/Auschaltplanungen wird jetzt mit dem neuen Befehl clearStateDelayed gemacht //..................................Vorläufig wurde das Merken der letzten Aktion geloescht, da es keine Verwendung im Moment hat //..........Version 0.75 27.01.2015 Fehler beim Loeschen von Ein/Auschaltplanungen behoben - Es wurde nicht geloescht, wenn Verbraucher eingeschaltet bleiben sollen //..........Version 0.80 28.04.2016 Fehler mit der Astrozeit, wenn die BisZeit < ist als die Astrozeit(von) beseitigt //..........Version 0.90 23.12.2017 Einund Ausschaltbefehle jetzt als Variable einstellbar. Damit lassen sich auch andere Geräte einbindungen (z.B KNX mit 0 und 1). Level und STATE Geräte als Boolean und number identifziert //..........Version 0.91 19.01.2018 Ein Ausschaltbefehl war noch nicht mit der Ausschaltvariable verknüpft //..................................Die IDAWSaktiv war mit einem falschen Datenpunkt verknüpft //..........Version 0.92.03.12.2018.Fehler behoben nach update auf JS 4.0.1 !fs.existsSync funktioniert nicht mehr ausgetausch mit fs.readFile //..........Version 0.94.27.01.2019 Fehler behoben: Wenn Zeit in den nächsten Tag reichte, dann wurden beu Astronutzung die Start und Endzeiten nicht richtig berechnet //................................. Sonnenaufgang und Sonnenuntergang können statt der Zeitangabe eingegeben werden. //................................. In der VonZeit kann jetzt auch Sonnenaufgang eingegeben werden //................................. Debug der Zeitenberechnung eingeführt // // Das Script wird aktiviert, wenn das Flag "Anwesenheitssteuerung gesetzt wird" // HIER Einstellungen vornehmen............................................................................................ var KeyWordSunDown = "SunSet"; // SONNENUNTERGANG - Bitte dieses Keyword in ZeitxVon oder ZeitxBis eintragen wenn Astrozeit gewünscht ist var KeyWordSunUp = "SunRise"; // SONNENAUFGANG - Bitte dieses Keyword in ZeitxVon oder ZeitxBis eintragen wenn Astrozeit gewünscht ist // Bei Eingabe des Keywords bei den Zeiten werden die Astrozeiten verwendet // Einstellungen der Aktivzeiten je IDGruppe von bis var zeit1von = "SunSet"; //Aktivzeit von IDGruppe1 var zeit1bis = "18:30:00"; //Aktivzeit bis IDGruppe1 var zeit2von = "20:15:00"; //Aktivzeit von IDGruppe2 var zeit2bis = "23:30:00"; //Aktivzeit bis IDGruppe2 var zeit3von = "23:30:00"; //Aktivzeit von IDGruppe3 var zeit3bis = "01:00:00"; //Aktivzeit bis IDGruppe3 var zeit4von = "20:00:00"; //Aktivzeit von IDGruppe4 var zeit4bis = "03:00:00"; //Aktivzeit bis IDGruppe4 var zeit5von = "19:00:00"; //Aktivzeit von IDGruppe5 var zeit5bis = "23:00:00"; //Aktivzeit bis IDGruppe5 // Einstellungen der zufaelligen Einschaltdauer je IDGruppe von bis var ein1von = 1; // Minuten IDGruppe1 von var ein1bis = 5; // Minuten IDGruppe1 bis var ein2von = 10; // Minuten IDGruppe2 von var ein2bis = 30; // Minuten IDGruppe2 bis var ein3von = 5; // Minuten IDGruppe3 von var ein3bis = 10; // Minuten IDGruppe3 bis var ein4von = 5; // Minuten IDGruppe4 von var ein4bis = 10; // Minuten IDGruppe4 bis var ein5von = 10; // Minuten IDGruppe5 von var ein5bis = 30; // Minuten IDGruppe5 bis // Einstellung je Gruppe für die maximale Startverzögerung in Minuten // bei 0 = keine Startverzögerung - bei z.B. 10 = Startverzögerung zwischen 0 und 10 in Minuten // var StartDelay1 = 1; // Maximale Startverzoegerung Gruppe1 var StartDelay2 = 5; // Maximale Startverzoegerung Gruppe2 var StartDelay3 = 5; // Maximale Startverzoegerung Gruppe3 var StartDelay4 = 5; // Maximale Startverzoegerung Gruppe4 var StartDelay5 = 0; // Maximale Startverzoegerung Gruppe5 // Einstellung Check-schedule - Voreinstellung z.B. alle 30 Minuten je IDGruppe - Damit wird je Lauf nach Zufaelligkeit je ein Geraet der IDGruppe eingeschaltet var cron1 = 2; // checks alle x Minuten für IDGruppe1 var cron2 = 15; // checks alle x Minuten für IDGruppe2 var cron3 = 15; // checks alle x Minuten für IDGruppe3 var cron4 = 5; // checks alle x Minuten für IDGruppe4 var cron5 = 0; // checks alle x Minuten für IDGruppe5 // Einstellung teilnehmende Homematic Geräte je IDGruppe maximal 5 - Eingabe der Homematic ID var IDGruppe11 = "hm-rpc.0.JEQ0036841.1.STATE"; // Licht Wohnzimmer Esstisch Stehlampe var IDGruppe12 = "hm-rpc.0.IEQ0379466.1.STATE"; // Licht Terrassentuere var IDGruppe13 = "hm-rpc.0.JEQ0038530.1.STATE"; // Licht Flur oben unten; var IDGruppe14 = "hm-rpc.0.JEQ0039785.1.STATE"; // Licht Kinderbad var IDGruppe15 = "hm-rpc.0.JEQ0038876.1.STATE"; // Licht Hobbyraum var Grp1ZufAnz = 5; // Anzahl der Geräte zur zufälligen Bestimmung des Geraetes var IDGruppe21 = "hm-rpc.0.JEQ0038535.1.STATE"; // Licht Flur oben Wand; var IDGruppe22 = "hm-rpc.0.IEQ0379466.1.STATE"; // Licht Terrassentuere var IDGruppe23 = "hm-rpc.0.JEQ0036841.1.STATE"; // Licht Wohnzimmer Esstisch Stehlampe var IDGruppe24 = " "; var IDGruppe25 = " "; var Grp2ZufAnz = 3; // Anzahl der Geräte zur zufälligen Bestimmung des Geraetes var IDGruppe31 = "hm-rpc.0.JEQ0038535.1.STATE"; // Licht Flur oben Wand; var IDGruppe32 = "hm-rpc.0.JEQ0038530.1.STATE"; // Licht Flur oben unten; var IDGruppe33 = "hm-rpc.0.JEQ0039785.1.STATE"; // Licht Kinderbad var IDGruppe34 = " "; var IDGruppe35 = " "; var Grp3ZufAnz = 5; // Anzahl der Geräte zur zufälligen Bestimmung des Geraetes var IDGruppe41 = "hm-rpc.0.LEQ1289934.4.STATE"; // Licht aussen Steinterrasse var IDGruppe42 = "hm-rpc.0.JEQ0039785.1.STATE"; // Licht Kinderbad var IDGruppe43 = "hm-rpc.0.JEQ0038483.1.STATE"; // Licht Schwimmbad Nebenlicht; var IDGruppe44 = " "; var IDGruppe45 = " "; var Grp4ZufAnz = 3; // Anzahl der Geräte zur zufälligen Bestimmung des Geraetes var IDGruppe51 = " "; var IDGruppe52 = " "; var IDGruppe53 = " "; var IDGruppe54 = " "; var IDGruppe55 = " "; var Grp5ZufAnz = 5; // Anzahl der Geräte zur zufälligen Bestimmung des Geraetes var logflag = true; // wenn auf true dann wird das logging in Datei /opt/iobroker/iobroker-data/AWSLog.csv eingeschaltet bei false vice versa var ausflag = true; // Wenn AWS deaktiviert wird, dann werden alle Teilnehmer ausgeschaltet // Experten-Einstellungen ....................................................................................................... var IDAWSaktiv = "javascript.0.Anwesenheitssteuerung.AWSTest"; // in den objekten angelegte variable zur Bestimmung ob AWS aktiv ist - Kann auch ausgetauscht werden durch eine andere var LogPath = "/opt/iobroker/iobroker-data/AWSLogTest.csv"; // Pfad und Dateiname des externen Logs var IgnoreWhenOn = false; // bei true: Ignoriert den Schaltvorgang, wenn das Geraet bereits eingeschaltet war var ErlieastSunDown = 16; // Die Stunde des fruehesten Sonnenuntergangs z.B. in Deutschlnad 16 Uhr var EarliestSunUp = 4; // Die Stunde des fruehesten Sonnenuntergangs z.B. in Deutschlnad 4 Uhr var LatestSunDown = 21; // Die Stunde des spätesten Sonnenuntergangs z.B. in Deutschlnad 21 Uhr var LatestSunUp = 8; // Die Stunde des spätestens Sonnenuntergangs z.B. in Deutschlnad 8 Uhr var EinschaltFlag = true; // Einschaltbefehl der Teilnehmer fuer Boolean Geräte var AusschaltFlag = false; // Ausschaltbefehl der Teilnehmer fuer Boolean Geräte var DimmAusschalt = 0; // Ausschaltbefehl fuer Number Geräte (Dimmer) var DimmEinschalt = 100; // Einschaltbefehl fuer Number Geräte (Dimmer) = Einschaltlevel auf den geschaltet wird var debug = false; // zusätzliche log Meldungen zur Analyse // Ende Experten-Einstellungen ....................................................................................................... // globale Variablen var fs = require('fs'); // enable write fuer externes log var cron1job = "*/"+cron1+" * * * *"; // CRON pattern aufgrund der Vorgabe in den Einstellungen var cron2job = "*/"+cron2+" * * * *"; // CRON pattern aufgrund der Vorgabe in den Einstellungen var cron3job = "*/"+cron3+" * * * *"; // CRON pattern aufgrund der Vorgabe in den Einstellungen var cron4job = "*/"+cron4+" * * * *"; // CRON pattern aufgrund der Vorgabe in den Einstellungen var cron5job = "*/"+cron5+" * * * *"; // CRON pattern aufgrund der Vorgabe in den Einstellungen var x = 0; // Geraetenummer der Gruppe, die zufaellig ausgewaehlt wurde var y = 0; // Einschaltzdauer aufgrund der Zufallszahl in Millisekunden var z = 0; // Einschaltverzögerung aufgrund der Zufallszahl var string = " "; // Logstring var logtext=" " ; // Kommentar im log var objIDGruppe = " "; // uebergabe an Funktion der IDGruppe zum Schalten des Geraetes var SpaceChk = new RegExp(/\s/); // pattern um zu pruefen ob eine IDGruppe blanks enthaelt var SwitchTimes = []; // SwitchTimes wird genutzt um die Schaltzeiten zu merken. Das wird benötigt um Schaltzeiten die in den nächsten Tag reichen zu verwalten // Struktur 0 = Schaltgruppe, 1 = vonZeit, 2 = bisZeit // Aktivierungsflag anlegen beim ersten Start des Scripts createState(IDAWSaktiv, true, {read: true, write: true, type: 'boolean', name: 'Anwesenheitssteuerungsflag', desc: 'Anwesenheitssteuerungsflag'}); // Execute IDGruppe1 //------------------------------------------------------------------------------------------------------------------------------------------------------- schedule(cron1job, function() { if (getState(IDAWSaktiv).val === true) { // AWS aktiv ? if(IsTimeInRange(zeit1von, zeit1bis,1)) { // ist die "von"-Zeit innerhalb des aktuellen Zeitfensters ? x = zufall(1,Grp1ZufAnz,x); // Ermittlung zufaelliges Geraet zum enschalten z = zufall(0,StartDelay1*60,y)*1000; // Ermittlung der Einschaltverzögerung aufgrund der Zufallszahl y = zufall(ein1von*60,ein1bis*60,y)*1000; // Ermittlung der Einschaltzdauer aufgrund der Zufallszahl in Millisekunden var IDGruppe = "IDGruppe1" + x; // Ermittlung Gruppenname z.B. IDGruppe11 if (x <= 5 && GeraetExists(IDGruppe)) { AWSSchaltung(IDGruppe,y,z); } // Geraetenummer muss 1 - 5 sein, dass Geraet muss existieren dann schalten } // Ende Zeitcheck } // Endeif für AWS-Aktivflag check }); // end schedule IDGruppe1 // Execute IDGruppe2 //------------------------------------------------------------------------------------------------------------------------------------------------------- schedule(cron2job, function() { if (getState(IDAWSaktiv).val === true) { // AWS aktiv ? if(IsTimeInRange(zeit2von, zeit2bis,2)) { // ist die "von"-Zeit innerhalb des aktuellen Zeitfensters ? x = zufall(1,Grp2ZufAnz,x); // Ermittlung zufaelliges Geraet zum enschalten z = zufall(0,StartDelay2*60,y)*1000; // Ermittlung der Einschaltverzögerung aufgrund der Zufallszahl y = zufall(ein2von*60,ein2bis*60,y)*1000; // Ermittlung der Einschaltzdauer aufgrund der Zufallszahl in Millisekunden var IDGruppe = "IDGruppe2" + x; // Ermittlung Gruppenname z.B. IDGruppe21 if (x <= 5 && GeraetExists(IDGruppe)) { AWSSchaltung(IDGruppe,y,z); } // Geraetenummer muss 1 - 5 sein, dass Geraet muss existieren dann schalten } // Ende Zeitcheck } // Endeif für AWS-Aktivflag check }); // end schedule IDGruppe2 // Execute IDGruppe3 //------------------------------------------------------------------------------------------------------------------------------------------------------- schedule(cron3job, function() { if (getState(IDAWSaktiv).val === true) { // AWS aktiv ? if(IsTimeInRange(zeit3von, zeit3bis,3)) { // ist die "von"-Zeit innerhalb des aktuellen Zeitfensters ? x = zufall(1,Grp3ZufAnz,x); // Ermittlung zufaelliges Geraet zum enschalten z = zufall(0,StartDelay3*60,y)*1000; // Ermittlung der Einschaltverzögerung aufgrund der Zufallszahl y = zufall(ein3von*60,ein3bis*60,y)*1000; // Ermittlung der Einschaltzdauer aufgrund der Zufallszahl in Millisekunden var IDGruppe = "IDGruppe3" + x; // Ermittlung Gruppenname z.B. IDGruppe31 if (x <= 5 && GeraetExists(IDGruppe)) { AWSSchaltung(IDGruppe,y,z); } // Geraetenummer muss 1 - 5 sein, dass Geraet muss existieren dann schalten } // Ende Zeitcheck } // Endeif für AWS-Aktivflag check }); // end schedule IDGruppe3 // Execute IDGruppe4 //------------------------------------------------------------------------------------------------------------------------------------------------------- schedule(cron4job, function() { if (getState(IDAWSaktiv).val === true) { // AWS aktiv ? if(IsTimeInRange(zeit4von, zeit4bis,4)) { // ist die "von"-Zeit innerhalb des aktuellen Zeitfensters ? x = zufall(1,Grp4ZufAnz,x); // Ermittlung zufaelliges Geraet zum enschalten z = zufall(0,StartDelay4*60,y)*1000; // Ermittlung der Einschaltverzögerung aufgrund der Zufallszahl y = zufall(ein4von*60,ein4bis*60,y)*1000; // Ermittlung der Einschaltzdauer aufgrund der Zufallszahl in Millisekunden var IDGruppe = "IDGruppe4" + x; // Ermittlung Gruppenname z.B. IDGruppe41 if (x <= 5 && GeraetExists(IDGruppe)) { AWSSchaltung(IDGruppe,y,z); } // Geraetenummer muss 1 - 5 sein, dass Geraet muss existieren dann schalten } // Ende Zeitcheck } // Endeif für AWS-Aktivflag check }); // end schedule IDGruppe4 // Execute IDGruppe5 //------------------------------------------------------------------------------------------------------------------------------------------------------- schedule(cron5job, function() { if (getState(IDAWSaktiv).val === true) { // AWS aktiv ? if(IsTimeInRange(zeit5von, zeit5bis,5)) { // ist die "von"-Zeit innerhalb des aktuellen Zeitfensters ? x = zufall(1,Grp5ZufAnz,x); // Ermittlung zufaelliges Geraet zum enschalten z = zufall(0,StartDelay5*60,y)*1000; // Ermittlung der Einschaltverzögerung aufgrund der Zufallszahl y = zufall(ein5von*60,ein5bis*60,y)*1000; // Ermittlung der Einschaltzdauer aufgrund der Zufallszahl in Millisekunden var IDGruppe = "IDGruppe5" + x; // Ermittlung Gruppenname z.B. IDGruppe51 if (x <= 5 && GeraetExists(IDGruppe)) { AWSSchaltung(IDGruppe,y,z); } // Geraetenummer muss 1 - 5 sein, dass Geraet muss existieren dann schalten } // Ende Zeitcheck } // Endeif für AWS-Aktivflag check }); // end schedule IDGruppe5 // ------------------------Ruecksetzen der Timeouts /Ausschalten der teilnehmenden Geraete, wenn AWS-Aktiv auf false gesetzt wird-------------- on({id: IDAWSaktiv, val: false }, function(obj) // Event: wenn AWS Flag auf nicht aktiv gesetzt wurde { var objGruppeI = " "; // Baut die IDGruppe zusammen Position 1 var objGruppeJ = " "; // Baut die IDGruppe zusammen Position 2 var countobj = 0; //counter fuer Verzoegerungen zwischen den Ausschaltungen var id; var object; for (var i = 1; i <= 5; i++) { // Loop fuer die Gruppen-Nr objGruppeI = "IDGruppe" + i; // Loop fuer die Geraete Nr der IDGruppen 1 - 5 for (var j = 1; j <= 5; j++) { // Loop Position 2 /1 - 5 ) objGruppeJ = objGruppeI + j ; // Ermittlung Position 2 id = eval(objGruppeJ); if (SpaceChk.test(id)) { // Check for blanks } else { // keine blanks object = getObject(id); if (GeraetExists(objGruppeJ) === true) { // Gibt es das Geraet clearStateDelayed(id); // Alle Pläne der Gruppe loeschen if (ausflag) { // sollen die Teilnehmer ausgeschaltet werden ? if (object.common && object.common.type === 'boolean') { // ist es ein STATE Geraet ? setStateDelayed(id, AusschaltFlag, countobj); // ausschalten mit je 300 millisekunden wartezeit } if (object.common && object.common.type === 'number') { // ist es ein LEVEL Geraet ? setStateDelayed(id, DimmAusschalt, countobj); // ausschalten mit je 300 millisekunden wartezeit } } // endif check ob Geraete ausgeschaltet werden sollen countobj = countobj + 300; // alle 300 millisekunden schalten } // endif fuer Geraetecheck und switch off } // end Space Check } // Ende Position 2 Loop } // Ende Position 1 Loop log("EVENT AWS deaktiviert Der schedule zur geplanten Ausschaltung von Geraeten wurde zurueckgesetzt " ,"info"); string = ";;;;;;;AWS wurde deaktiviert - Der schedule zur geplanten Ausschaltung von Geraeten wurde zurueckgesetzt"; // bereite LOG vor writelog(string); // schreibe LOG in Datei if(debug ) { listcheckSwitch();} }); // ende on id // ------------------------schreibe Log wenn AWS aktiviert wurde-------------------------------------- on({id: IDAWSaktiv, val: true }, function(obj) // Event: wenn AWS Flag auf nicht aktiv gesetzt wurde { log("EVENT AWS wurde aktiviert " ,"info"); string = ";;;;;;;AWS wurde aktiviert"; // bereite LOG vor writelog(string); if(debug ) { listcheckSwitch();} }); // ende on id // ------------------------ F U N K T I O N E N ------------------------------------------------------- //----------------------------------------------------------------------------------------------------- // Diese Funktion schaltet die IDGruppenmitglieder der gerade zu berabeitenden IDGruppe //----------------------------------------------------------------------------------------------------- // neu function AWSSchaltung(objIDGruppe,y,z) { logtext = " "; var id = eval(objIDGruppe); var obj = getObject(id); if (!obj) return; if (obj.common && obj.common.type === 'boolean') { // ist es ein STATE Geraet ? if (getState(id).val == AusschaltFlag ) { // nur wenn noch nicht eingeschaltet setStateDelayed(id, EinschaltFlag, z); // Licht an in z millisekunden // var timer = setTimeout(function (){ // setState(eval(objIDGruppe),0); }, z+y); //Licht aus in y millisekunden (Einschaltverzoegerung plus Einschaltdauer) console.log('Routine AWSSchaltung - SET: ' + id + ' to false in ' + (z+y) + 'ms'); setStateDelayed(id, AusschaltFlag, z+y, false); //Licht aus in z+y millisekunden (Einschaltverzoegerung plus Einschaltdauer) } else { // else - Geraet ist schon eingeschaltet if (IgnoreWhenOn) { //keine Reaktion wenn Geraet bereits eingeschaltet war logtext = "keine Aktion - Geraet war bereits eingeschaltet"; } else { // else - es soll uebersteuert werden mit den neuen werten z = 0; // Einschaltverzoegerung setzen auf Null console.log('Routine AWSSchaltung - SET: ' + id + ' to false in ' + (z+y) + 'ms'); setStateDelayed(id, AusschaltFlag, z+y, true ); //Licht aus in z+y millisekunden (Einschaltverzoegerung plus Einschaltdauer) ohne Einschaltverzoegerung logtext = "Geraet war bereits eingeschaltet -- uebersteuert - ohne Einschaltverzoegerung - alter schedule geloescht- "; } // endeif IgnoreWhenOn } // Ende IF fuer Check ob bereits eingeschaltet } // Ende IF für STATE Geraete if (obj.common && obj.common.type === 'number') { // ist es ein LEVEL Geraet ? if (getState(id).val == DimmAusschalt ) { // nur wenn noch nicht eingeschaltet console.log('Routine AWSSchaltung - SET: ' + id + ' to ' + (obj.common.max || 100) + ' in ' + z + 'ms'); setStateDelayed(id, obj.common.max || DimmEinschalt, z); // Licht an in z millisekunden // var timer = setTimeout(function (){ // setState(eval(objIDGruppe),0); }, z+y); //Licht aus in y millisekunden (Einschaltverzoegerung plus Einschaltdauer) console.log('Routine AWSSchaltung - SET: ' + id + ' to ' + (obj.common.min || 0) + ' in ' + (z+y) + 'ms'); setStateDelayed(id, obj.common.min || DimmAusschalt, z+y, false); //Licht aus in y millisekunden (Einschaltverzoegerung plus Einschaltdauer) } else { // else - Geraet ist schon eingeschaltet if (IgnoreWhenOn) { //keine Reaktion wenn Geraet bereits eingeschaltet war logtext = "keine Aktion - Geraet war bereits eingeschaltet"; } else { // else - es soll uebersteuert werden mit den neuen werten z = 0; // Einschaltverzoegerung setzen auf Null console.log('Routine AWSSchaltung - SET: ' + id + ' to ' + (obj.common.min || DimmAusschalt) + ' sofort'); setStateDelayed(id, obj.common.min || DimmAusschalt, z+y, true); //Licht aus in z+y millisekunden (Einschaltverzoegerung plus Einschaltdauer) ohne Einschaltverzoegerung logtext = "Geraet war bereits eingeschaltet -- uebersteuert - ohne Einschaltverzoegerung - alter schedule geloescht- "; } // endeif IgnoreWhenOn } // Ende IF fuer Check ob bereits eingeschaltet } // Ende IF für LEVEL Geraete var GeraeteName = getObject(id).common.name; // Name des Geraetes in Klartext var now = new Date(); // store current date and time var currSec = now.getTime(); // millisekunden seit 01.01.1970 /current millisecs var berechnEinZeit = millisecToDate( currSec + z); // millisecs in Zeit umrechnen fuer die Einschaltzeit var berechnAusZeit = millisecToDate(currSec + z + y); // millisecs in Zeit umrechnen fuer die Ausschaltzeit // WriteArray(objIDGruppe,timer, currSec + z, currSec + z + y) // Merken des Schaltvorganges string = objIDGruppe+";" + id +";" + GeraeteName + ";" + z/1000 + ";" +y/1000+";"+berechnEinZeit + ";" + berechnAusZeit + ";" + logtext; // bereite LOG vor log("Routine AWSSchaltung - EVENT " + objIDGruppe + "; " +id + "; " + GeraeteName + "; " + z/1000 + "; " + y/1000 + "; " + berechnEinZeit + "; " + berechnAusZeit + "; " + logtext, "info"); //Log schreiben writelog(string); // schreibe LOG in Datei logtext = " "; } // Ende Funktion //----------------------------------------------------------------------------------------------------- // Funktion zur Bestimmung einer ganzzahligen Zufallszahl innerhalb vorgegebener min/max Werte //----------------------------------------------------------------------------------------------------- function zufall(low,high,back) { back = Math.floor(Math.random() * (high - low + 1)) + low; // log("EVENT AWS Zufallszahlen - low = " + low + "high = " + high + " back = " + back ,"info"); return back; } // ende Funktion //----------------------------------------------------------------------------------------------------- // Funktion zur Ueberpruefung ob die angegebenen Geraete exisiteren //----------------------------------------------------------------------------------------------------- function GeraetExists(objGruppe) { var back = false; var id = eval(objGruppe); if (SpaceChk.test(id)) { // objIDGruppe darf kein space enthalten // ist ein Geraet ueberhaupt zugeordnet ? // log("Geraet hat kein assignment - Gruppe " + objGruppe, "info"); return back; } // endif IDGruppe hat kein assignment if (getState(id)) { // Existiert das Geraet ? back = true; } else { log("Routine GeraetExists - Geraet existiert nicht - bitte in den Einstellungen ueberpruefen - Gruppe " + objGruppe, "info"); } // endif check on Geraet exists return back; } // ende Funktion //----------------------------------------------------------------------------------------------------- // Funktion schreibt einen Logeintrag in das Filesystem und auch in das interne Log-System //----------------------------------------------------------------------------------------------------- function writelog(string) { if (logflag === true) { // Zerlege Datum und Zeit in Variable var now = new Date(); // store current date and time var year = now.getFullYear(); var month = addZero(now.getMonth()+1); var day = addZero(now.getDate()); var Thour = addZero(now.getHours()); var Tmin = addZero(now.getMinutes()); var Tsec = addZero(now.getSeconds()); var logdate = day + '.' + month + '.' + year; var logtime = Thour + ':' + Tmin + ':' + Tsec; fs.readFile(LogPath, 'utf8', function(err,data){ if (!err) { // File existiert fs.appendFileSync(LogPath, logdate+" ;"+logtime+" ;"+string + "\n"); // Füge Satz in Datei ein }else{ log("Routine writelog - Logfile nicht gefunden - wird angelegt"), "info"; var headerLine= "Datum;Uhrzeit;Gruppe;GeraeteID;Geraetebezeichnung;Einschaltverzoegerung;LaengeSchaltzeit;ZeitEin berechnet;ZeitAus berechnet;Kommentar" fs.appendFileSync(LogPath, headerLine + "\n"); // Füge Satz in Datei ein fs.appendFileSync(LogPath, logdate+" ;"+logtime+" ;"+string + "\n"); // Füge Satz in Datei ein } }); // ende Filecheck } ; // Ende check on logflag } // Ende Funktion //----------------------------------------------------------------------------------------------------- // Funktion IsTimeInRange - // Ermittlung ob die aktuelle Zeit in der vorgegebenen Schaltzeit liegt (inkl Astro) //----------------------------------------------------------------------------------------------------- function IsTimeInRange (zeitvon, zeitbis, Gruppe) { var now = new Date(); var lower; // enthält Javascript datums/Zeitformat für die VOM Zeit var upper; // enthält Javascript datums/Zeitformat für die BIS Zeit var astrovonDown = zeitvon.includes(KeyWordSunDown); // Astrozeit VON Sonnenuntergang gesetzt var astrovonUp = zeitvon.includes(KeyWordSunUp); // Astrozeit VON Sonnenaufgang gesetzt var astrobisDown = zeitbis.includes(KeyWordSunDown); // Astrozeit BIS Sonnenuntergang gesetzt var astrobisUp = zeitbis.includes(KeyWordSunUp); // Astrozeit BIS Sonnenaufgang gesetzt var astrovon = false; var astrobis = false; var StatusSwichTimes =checkSwitchTime(Gruppe); if (StatusSwichTimes) { // es gibt einen aktuellen Eintrag bzw laufende Schaltzeit fuer diese Gruppe if(debug ) { log("Routine IsTimeInRange - Gruppe"+ Gruppe + " ist im definierten Zeitrange - Schaltung ist aktiv", "info") } return true; // in Tabelle SwitchTime gibt es noch einen gültigen Eintrag also zurück zur Schaltung } // bei Verwendung von Astrozeiten werden die errechneten Zeiten in lower und upper gespeichert if (astrovonDown === true) { // Astrozeit gesetzt VON Zeit ist Sonnenuntergang lower = getAstroDate("sunsetStart"); astrovon = true; } if (astrovonUp === true) { // Astrozeit gesetzt VON Zeit ist Sonnenaufgang lower = getAstroDate("sunriseEnd"); astrovon = true; } if (astrobisDown === true) { // Astrozeit gesetzt BIS Zeit ist Sonnenuntergang upper = getAstroDate("sunsetStart"); if(astrovonDown) { // wenn VonZeit = untergang und BisZeit = Untergang - dann muss bis Zeit nächster Tag sein upper.setDate(upper.getDate() + 1); // 1 Tag (24 Stunden ) addieren da der bis Wert wahrscheinlich am nächsten Tag liegen muss } astrobis = true; } if (astrobisUp === true) { // Astrozeit gesetzt BIS Zeit ist Sonnenaufgang upper = getAstroDate("sunriseEnd"); if(astrovonDown) { // wenn VonZeit = aufgang und BisZeit = Aufgang - dann muss BIS Zeit nächster Tag sein upper.setDate(upper.getDate() + 1); // 1 Tag (24 Stunden ) addieren da der bis Wert wahrscheinlich am nächsten Tag liegen muss } astrobis = true; } // Wenn keine Astrozeiten verwendet werden werden Zeiten anhand der Zeitangaben errechnet if (!astrovon) { lower = addTime(zeitvon); // switch on time im berechenbaren Format } if (!astrobis) { upper = addTime(zeitbis); // switch off time im berechenbaren Format } // Sonderfall:wenn die Zeitangaben sind identisch - also bis zeit nächster Tag und von Zeit muss auf now liegen if (zeitvon === zeitbis) { upper.setDate(upper.getDate() + 1); // 24 Stunden zur Bis-Zeit Hinzufügen lower = now; // wenn z.B. von 23:00:00 bis 23:00:00 eingegeben wurde dann soll immer geschaltet werden } // Wenn jetzt noch die VON Zeit kleiner also die BIS Zeit ist muss die BIS Zeit evt auf den nächsten Tag gelegt werden. (oder auch sie ist abgelaufen) if (upper < lower) { // Die von Zeit ist groesser als die bis Zeit if(astrovonDown) { // im Falle von Astrovon kann es sein, dass die bis Zeit in den nächsten Tag geht if( upper.getHours() < ErlieastSunDown ) { // Uewberpruefen ob die BisZeit kleiner als der Schwellwert ist upper.setDate(upper.getDate() + 1); // 1 Tag (24 Stunden ) addieren da der bis Wert wahrscheinlich am nächsten Tag liegen muss if (debug) { log("Routine IsTimeInRange - Gruppe"+ Gruppe +" bei Astrovon die zeitbis started Morgen - AstroZeit Sonnenuntergang VON ist "+ lower ,"info");} } } if(astrovonUp) { // im Falle von Astrovon kann es sein, dass die bis Zeit in den nächsten Tag geht if( upper.getHours() < EarliestSunUp ) { // Uewberpruefen ob die BisZeit kleiner als der Schwellwert ist upper.setDate(upper.getDate() + 1); // 1 Tag (24 Stunden ) addieren da der bis Wert wahrscheinlich am nächsten Tag liegen muss if (debug) { log("Routine IsTimeInRange - Gruppe"+ Gruppe + " bei Astrovon die zeitbis started Morgen - AstroZeit Sonnenaufgang VON ist "+ lower,"info");} } } if(astrobisDown) { // im Falle von Astrovon kann es sein, dass die bis Zeit in den nächsten Tag geht if( lower.getHours() > LatestSunDown ) { // Uewberpruefen ob die vonZeit groesser als der Schwellwert ist upper.setDate(upper.getDate() + 1); // 1 Tag (24 Stunden ) addieren da der bis Wert wahrscheinlich am nächsten Tag liegen muss if (debug) { log("Routine IsTimeInRange - Gruppe"+ Gruppe + " bei Astrovon die zeitbis started Morgen - AstroZeit Sonnenuntergang BIS ist "+ upper,"info");} } } if(astrobisUp) { // im Falle von Astrovon kann es sein, dass die bis Zeit in den nächsten Tag geht if( lower.getHours() > LatestSunDown ) { // Uewberpruefen ob die VonZeit groesser als der Schwellwert ist upper.setDate(upper.getDate() + 1); // 1 Tag (24 Stunden ) addieren da der bis Wert wahrscheinlich am nächsten Tag liegen muss if (debug) { log("Routine IsTimeInRange - Gruppe"+ Gruppe + " bei Astrovon die zeitbis started Morgen- - AstroZeit Sonnenaufgang BIS ist "+ upper,"info");} } } if (!astrovon && !astrobis) { // wenn keine Astrozeit gesetzt ist und die bis Zeit kleiner ist --> nächster Tag für die BisZeit upper.setDate(upper.getDate() + 1); // 1 Tag (24 Stunden ) addieren da der bis Wert wahrscheinlich am nächsten Tag liegen muss } } if (debug) {log("Routine IsTimeInRange - Gruppe"+ Gruppe + " Berechnung der Zeiten: VON " + lower + " BIS " + upper,"info");} // Wenn jetzt noch die BIS Zeit kleiner also die VON Zeit ist, dann ist die Zeit abgelaufen if (upper < lower ) { // dies trifft zu wenn die astrozeit die realzeit eingeholt hat z.B. astrovon = 20:00 und bisZeit 19:00 if (debug) { log("Routine IsTimeInRange - Gruppe"+ Gruppe + " upper ist kleiner als lower - zurück Gruppe nicht (mehr) im Zeitrange false","info");} return false; } if( now >= lower && now <= upper ) { log("Routine IsTimeInRange - Gruppe"+ Gruppe + " aktuelle ist ist > als lower und kleiner als upper - Gruppe wird geschaltet (true)" ); UpdateSwithTime(Gruppe,lower,upper); // if(debug ) { listcheckSwitch(Gruppe);} return true; } else { log("Routine IsTimeInRange - Gruppe"+ Gruppe + " Zeit nicht im Zeitrange - keine Schaltung ") return false; } } //----------------------------------------------------------------------------------------------------- // Funktion checkSwithTime zum Finden in Tabelle SwitchTimes ob es einen Gültigen Eintrag innerhalb der Zeit gibt // Struktur SwitchTimes: 0 = Schaltgruppe, 1 = vonZeit, 2 = bisZeit //----------------------------------------------------------------------------------------------------- function listcheckSwitch() { for (var x in SwitchTimes) { log("Routine listcheckSwitch - Gruppe" +SwitchTimes[x][0] + " Zeitvon " + SwitchTimes[x][1] + " Zeitbis " + SwitchTimes[x][2],"info"); } } //----------------------------------------------------------------------------------------------------- // Funktion checkSwithTime zum Finden in Tabelle SwitchTimes ob es einen Gültigen Eintrag innerhalb der Zeit gibt // Struktur SwitchTimes: 0 = Schaltgruppe, 1 = vonZeit, 2 = bisZeit //----------------------------------------------------------------------------------------------------- function checkSwitchTime(Gruppe) { var now = new Date(); for (var x in SwitchTimes) { if(SwitchTimes[x][0] === Gruppe) { if( now >= SwitchTimes[x][1] && now <= SwitchTimes[x][2] ) { return true; } } } return false; } // Ende Function checkSwitchTime //----------------------------------------------------------------------------------------------------- // Funktion UpdateSwithTime macht einen update auf die Tabelle für ausgelaufene Schaltzeiten und für neue // Struktur SwitchTimes: 0 = Schaltgruppe, 1 = vonZeit, 2 = bisZeit //----------------------------------------------------------------------------------------------------- function UpdateSwithTime(Gruppe,VonZeit,BisZeit) { for (var x in SwitchTimes) { if(SwitchTimes[x][0] === Gruppe) { if(debug){ log("Routine UpdateSwithTime - Gruppe " + Gruppe + " Switchtime Update VON " + VonZeit + " BIS " + BisZeit,"info" );} SwitchTimes[Gruppe][1] = VonZeit; SwitchTimes[Gruppe][2] = BisZeit; return; } } SwitchTimes.push([Gruppe, VonZeit, BisZeit]); // nicht gefunden - also hinzufügen if(debug){ log("Routine UpdateSwithTime - Gruppe" + Gruppe + " Switchtime hinzufuegen VON " + VonZeit + " BIS " + BisZeit,"info" );} } //----------------------------------------------------------------------------------------------------- // Funktion zur Erzeugung von führenden Nullen für das Datum Format //----------------------------------------------------------------------------------------------------- function addZero(i) { if (i < 10) { i = "0" + i; } return i; } // Ende Funktion //----------------------------------------------------------------------------------------------------- // Funktion Millisekunden in Datum/Zeit umrechnen /wird für logging benoetigt //----------------------------------------------------------------------------------------------------- function millisecToDate(millisec) { var time = new Date(millisec); var Thour = addZero(time.getHours()); var Tmin = addZero(time.getMinutes()); var Tsec = addZero(time.getSeconds()); var datum = Thour + ':' + Tmin + ':' + Tsec; return datum; } // Ende Funktion //----------------------------------------------------------------------------------------------------- //Funktion addTime wandelt einen String mit Format 00:00:00 in rechenbare Zeit um //----------------------------------------------------------------------------------------------------- function addTime(strTime) { var d = new Date(); d = new Date(d.getFullYear(), d.getMonth(), d.getDate()) var time = strTime.split(':'); d.setHours(time[0]); d.setMinutes(time[1]); d.setSeconds(time[2]); return d; }