Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. Best Practice für Uhrzeiten gesucht

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    Best Practice für Uhrzeiten gesucht

    This topic has been deleted. Only users with topic management privileges can see it.
    • T
      TobStar last edited by

      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 🙂

      1 Reply Last reply Reply Quote 0
      • T
        TobStar last edited by TobStar

        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;
        }
        
        1 Reply Last reply Reply Quote 0
        • AlCalzone
          AlCalzone Developer last edited by

          Du könntest die Library Moment.js verwenden. Damit kannst du z.B. deine Zeiten im Format "HHMM" parsen und vergleichen.

          1 Reply Last reply Reply Quote 0
          • OstfrieseUnterwegs
            OstfrieseUnterwegs last edited by

            Kannst Du nicht einfach compareTime benutzen?

            T 1 Reply Last reply Reply Quote 1
            • T
              TobStar @OstfrieseUnterwegs last edited by

              @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') );
              
              1 Reply Last reply Reply Quote 0
              • OstfrieseUnterwegs
                OstfrieseUnterwegs last edited by

                Man kann doch 'not between' benutzen

                log( compareTime('2:00', '20:00', 'not between', '21:00') );
                //--> true
                
                1 Reply Last reply Reply Quote 1
                • OstfrieseUnterwegs
                  OstfrieseUnterwegs last edited by

                  Hier ist noch ein Thread mit ähnlichem Problem

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post

                  Support us

                  ioBroker
                  Community Adapters
                  Donate

                  516
                  Online

                  31.9k
                  Users

                  80.2k
                  Topics

                  1.3m
                  Posts

                  javascript
                  3
                  7
                  1201
                  Loading More Posts
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes
                  Reply
                  • Reply as topic
                  Log in to reply
                  Community
                  Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                  The ioBroker Community 2014-2023
                  logo