NEWS
Best Practice für Uhrzeiten gesucht
-
Hallo zusammen,
ich programmiere meine Scripte immer über JavaScript, habe aber an Stellen, an denen ich wissen muss ob etwas zu der Zeit z.B. eingeschaltet sein soll Probleme und wollte mal fragen wie Ihr das löst.
Ich setze z.B. Power Plugs ein, die u.a. zur Stromersparnis einen WLAN Repeater / Fernseher / Raspberry ein- / ausschaltet. Möglich ist es aber auch das ganze per Anwesenheit zu steuern, das Script selbst muss universal sein.
Fallbeispiele:
Das Script schaltet um 18:00 Uhr den Plug ein und um 02:00 Uhr wieder aus, dazu nutze ich ein Zeitobjekt in iOBroker.on("javascript.0.Globale_Parameter.Uhrzeit", function (obj) { var Zeiten = JSON.parse(Zeitfunktion()); var AktZeit = getState('javascript.0.Globale_Parameter.Uhrzeit').val.replace(':', ''); Verbraucher.forEach(function(device){ var Einschaltzeit = getState(Pfad +'.'+ device[1] +'.Zeitsteuerung_Ein').val; var Ausschaltzeit = getState(Pfad +'.'+ device[1] +'.Zeitsteuerung_Aus').val; if(getState(Pfad +'.'+ device[1] +'.Zeitsteuerung').val === true){ //Verbraucher Einschalten if( (Number(AktZeit) - Number(Einschaltzeit.replace(':', '')) === 0) && getState(device[0]).val === false){ //FORCE Anwesenheit if(getState(Pfad +'.'+ device[1] +'.Anwesenheit').val === false || (getState(Pfad +'.'+ device[1] +'.Anwesenheit').val === true && getState('javascript.0.Standort.Anwesend').val > 0) ){ setState(device[0], true); lastRun(Pfad +'.'+ device[1], Zeiten.Stunde +':'+ Zeiten.Minute); } } //Verbraucher Ausschalten if( (Number(AktZeit) - Number(Ausschaltzeit.replace(':', '')) === 0) && getState(device[0]).val === true){ setState(device[0], false); lastRun(Pfad +'.'+ device[1], Zeiten.Stunde +':'+ Zeiten.Minute); } } }); });
Das Script vergleicht die Uhrzeiten indem ich HH:MM in HHMM schreibe und diese subtrahiere (Gewünschte Zeit - Aktuelle Zeit), wenn 0 dann ausführen. Außerdem wird, falls gewünscht auch die Anwesenheit überprüft.
Nun aber der für mich schwierige Part, wenn ich das ganze nun aber auch per Anwesenheit schalten möchte, muss ich wissen ob der Plug zu dieser Zeit überhaupt eingeschalten werden sollte, sprich ob sich die aktuelle Uhrzeit innerhalb der Ein- / Ausschaltzeit befindet. In meinem Fall also zwischen 18:00 Uhr und 02:00 Uhr. Wie würdet Ihr das vergleichen?
//-- Bei Änderung der Anwesenheit --// on("javascript.0.Standort.Anwesend", function (obj) { var Zeiten = JSON.parse(Zeitfunktion()); //Wenn alle abwesend if(getState('javascript.0.Standort.Anwesend').val === 0){ Verbraucher.forEach(function(device){ if(getState(Pfad +'.'+ device[1] +'.Anwesenheit').val === true){ setState(device[0], false); lastRun(Pfad +'.'+ device[1], Zeiten.Stunde +':'+ Zeiten.Minute); } }); } //Wenn jemand anwesend else if(getState('javascript.0.Standort.Anwesend').val > 0) { Verbraucher.forEach(function(device){ if(getState(Pfad +'.'+ device[1] +'.Anwesenheit').val === true){ setState(device[0], true); lastRun(Pfad +'.'+ device[1], Zeiten.Stunde +':'+ Zeiten.Minute); } }); } });
Sowas wie if(AktuelleZeit < Ausschaltzeit && AktuelleZeit > Einschaltzeit) würde nicht funktionieren. Solche Szenarien habe ich immer wieder mal, das kann ich aber meist lösen weil es alles am selben Tag befindet. Hier wird am Vortag eingeschalten und am nachfolgendem Tag ausgeschalten.
Danke für euren Input
-
So, ich habe mir für diesen Fall nun mal eine Funktion geschrieben. Evtl. hilft Sie ja jemandem weiter, sorry wegen des Doppelposts ... hier mal meine bisherigen Zeitfunktionen.
function Zeitfunktion(){ var Tage = ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag']; var Zeit = new Date(); var Tag = Tage[Zeit.getDay()]; var Uhrzeit = Zeit.toLocaleTimeString().split(':'); return JSON.stringify({ 'Timestamp':Date.now(), 'Jahr':Zeit.getFullYear(), 'Tag':Tag, 'Stunde':Uhrzeit[0], 'Minute':Uhrzeit[1], 'ZTag': leadingZero(Zeit.getDate()), 'ZMonat':leadingZero((Zeit.getMonth()+1)), 'DIM': new Date(Zeit.getFullYear(), leadingZero((Zeit.getMonth()+1)), 0).getDate() }); } function addMinutes(time, offset){ // Uhrzeit wird in Stunden und Minuten geteilt var elements = time.split(":"); var hours = elements[0]; var minutes = elements[1]; // Aufrunden des Offsets fuer den Fall, dass eine Fliesskommazahl uebergeben wird var roundOffset = Math.ceil(offset); // Umrechnen der Uhrzeit in Minuten seit Tagesbeginn var timeSince24 = (hours * 60) + parseInt(minutes); // Addieren des uebergebenen Offsets timeSince24 = timeSince24 + parseInt(roundOffset); // Ueberlaufbehandlung if(timeSince24 < 0) timeSince24 = timeSince24 + 1440; else if(timeSince24 > 1440) timeSince24 = timeSince24 - 1440; // Errechnen von Stunden und Minuten aus dem Gesamtzeit seit Tagesbeginn var resMinutes = timeSince24 % 60; var resHours = (timeSince24 - resMinutes)/60; // Sicherstellen, dass der Wert fuer Minuten immer zweistellig ist if(resMinutes < 10) resMinutes = "0" + resMinutes; // Ausgabe des formatierten Ergebnisses return resHours + ":" + resMinutes; } function ZeitInner(start, ende){ var Zeiten = JSON.parse(Zeitfunktion()); if(ende < start) { ende = timestampVonUhrzeit(ende, true); start = timestampVonUhrzeit(start); } else { ende = timestampVonUhrzeit(ende); start = timestampVonUhrzeit(start); } if(Zeiten.Timestamp >= start && Zeiten.Timestamp <= ende) return true; else return false; }; function timestampVonUhrzeit(Uhrzeit, nextday=false){ var Datum; var Zeiten = JSON.parse(Zeitfunktion()); if(nextday === true){ //Prüfen ob Zeit im nächsten Monat if(Number(Zeiten.ZTag+1) > Zeiten.DIM) { var Tag = '01'; var Monat = leadingZero(Number(Zeiten.ZMonat) +1); var Jahr = Zeiten.Jahr; //Prüfen ob Zeit im nächsten Jahr if(Number(Monat) > 12) { Monat = '01'; Jahr = Number(Zeiten.Jahr) +1; } Datum = Monat +'/'+ Tag +'/'+ Jahr; } else Datum = Zeiten.ZMonat +'/'+ leadingZero(Number(Zeiten.ZTag) +1) +'/'+ Zeiten.Jahr; } else Datum = Zeiten.ZMonat +'/'+ Zeiten.ZTag +'/'+ Zeiten.Jahr; return new Date(Datum +' '+ Uhrzeit +':00').getTime(); } function leadingZero(i){ if(i < 10) i = '0'+ i; return i; }
-
Du könntest die Library Moment.js verwenden. Damit kannst du z.B. deine Zeiten im Format "HHMM" parsen und vergleichen.
-
Kannst Du nicht einfach compareTime benutzen?
-
@OstfrieseUnterwegs sagte in Best Practice für Uhrzeiten gesucht:
Kannst Du nicht einfach compareTime benutzen?
Da stößt man ebenfalls auf das Problem, das er nicht berücksichtigt das es sich ggf. um den nächsten Tag handelt. Das funktioniert nur für Events wo z.B. um 8 Uhr eingeschalten und um 10 Uhr ausgeschalten wird.
//ERGEBNIS IST FALSE log( compareTime('20:00', '02:00', 'between', '21:00') ); //ERGEBNIS IST TRUE log( compareTime('08:00', '10:00', 'between', '09:00') );
-
Man kann doch 'not between' benutzen
log( compareTime('2:00', '20:00', 'not between', '21:00') ); //--> true
-
Hier ist noch ein Thread mit ähnlichem Problem