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;
    }
    

  • Developer

    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


Log in to reply
 

Suggested Topics

  • 145
  • 5
  • 7
  • 6
  • 4
  • 11
  • 11
  • 3

1.9k
Online

32.1k
Users

38.7k
Topics

525.3k
Posts