Ankündigung

Einklappen
Keine Ankündigung bisher.

Behandlung von Uhrzeiten

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Behandlung von Uhrzeiten

    Hallo,

    ich habe Probleme mit der Behandlung von Uhrzeiten. Aktuelle Herausforderung:
    Ich habe die Items
    Code:
    DateTime Sunrise_Time "Sunrise [%1$tH:%1$tM]" <sunup>  (gAstro) {astro="type=SUNRISE_TIME"}
    DateTime sq_alarm_time "Weckzeit [%1$tT]"    <uhr>    (gPlayerSchlafzimmer)    { exec="<[/opt/usr//openhab/scripts/getAlarmTimes.pl:3600000:REGEX((.*?))]" }
    Der Inhalt der Items ist z.B.:
    Sunrise_Time: 2014-07-08T05:18:00
    sq_alarm_time: 06:20

    Ich möchte eine Regel erstellen, die die Rollos nicht vor der Weckzeit (sq_alarm_time) hochfährt, aber auch erst dann, wenn die Sonne aufgegangen ist.
    Leider habe ich keine Ahnung, wie ich in einer Rule diese zwei Zeiten vergleichen kann.

    Von der Logik sollte es so sein:

    Code:
    rule "Weckzeit"
    when
    //jede Minute ausführen
        Time cron "0 * * * * ?" 
    then
    if (jetzt >= sq_alarm_time && jetzt >= Sunrise_Time) {
       fahre rollos hoch
    }
    Irgendwie muss ich erstmal die drei Zeiten (jetzt, sq_alarm_time und Sunrise_Time) in ein einheitliches Format bringen: z.B. hh:mm, dann eine Methode haben, welche die Zeiten vergleichen kann.

    Für jede Hilfe wäre ich sehr dankbar.

    Viele Grüße
    Michael

    #2
    versuchs mal damit, ist zwar nicht sonderlich elegant, sollte aber seinen zweck erfüllen:

    items:
    switch sw_sunrise "Sonnenaufgang"
    group g_sunrise_up // hier noch die Rollos rein

    rules:
    import org.openhab.core.types.*
    import org.joda.time.*
    import org.openhab.model.script.actions.Timer

    var Timer tSunrise
    var Timer tWakeup


    rule "Weckzeit"

    when
    Time cron "0 0 3 * * ?" // nachts um drei ausführen, reicht

    then
    var year = now.getYear
    var month = now.getMonthOfYear
    var day = now.getDayOfMonth
    var datum = year+"-"+month+"-"+day+" "+strSunset.state
    var DateTime sunrise = parse(year+"-"+month+"-"+day+"T"+Sunrise_Time.state) // deine Variable „Sunrise_Time“
    var DateTime wakeup = parse(year+"-"+month+"-"+day+"T"+sq_alarm_time.state) // deine Variable „sq_alarm_time“

    if(tSunrise!=null) {
    tSunrise.cancel()
    }

    if(tWakeup!=null) {
    tWakeup.cancel()
    }

    tSunrise = createTimer(sunrise.plusMinutes(5)) [|
    logInfo("Sunrise“,“Timer tSunrise executed")
    sendCommand(sw_sunrise, ON)
    )
    ]

    tWakeup = createTimer(wakeup.plusMinutes(0)) [|
    logInfo("Wakeup","Timer tWakeup executed")

    // hier noch deinen regulären Alarm rein, z.B: pushNotification("Info", "Aufstehen!")

    if (sw_sunrise.state == ON) {
    g_sunrise_up?.members.forEach(Switch|
    sendCommand(Switch, ON)
    }
    )
    ]

    end

    Kommentar


      #3
      Hey stardriver2k,

      vielen Dank für Deine Mühe!!!
      Nur, damit ich auch verstehe was da passiert:
      Code:
      var datum  = year+"-"+month+"-"+day+" "+strSunset.state
          var DateTime sunrise = parse(year+"-"+month+"-"+day+"T"+Sunrise_Time.state) // deine Variable „Sunrise_Time“
          var DateTime wakeup = parse(year+"-"+month+"-"+day+"T"+sq_alarm_time.state) // deine Variable „sq_alarm_time“
      Wafür wird var datum benötigt?
      Was macht die Methode parse()? Es sieht so aus, als würde das Datum ermittelt werden (year, month, day), oder wird damit die Uhrzeit raus"geparsed"?

      Tja, und dann verlassen mich meine Kenntnisse. Was ich vermisse, ist ein Vergleich der Uhrzeit "jetzt" (time.now) mit der Uhrzeit "wakeup" und der Uhrzeit "sunrise".
      Vielleicht hatte ich das auch nicht verständlich genug ausgedrückt. Ich möchte, dass die Rollos nicht vor wakeup hochfahren und sie sollen auch erst dann hochgefahren werden, wenn es draußen hell ist (sunrise).
      Also muss die Bedingung (jetzt >= wakeup && jetzt >= sunrise) erfüllt sein.

      Die Timer von Dir verstehe ich leider nicht. Ich würde mich aber freuen, wenn Du mich erhellen könntest ;-)

      Aber jetzt schon mal vielen Dank für Deine Mühe!

      Viele Grüße Michael

      Kommentar


        #4
        Oh mann, wenn ich nur ein bisschen mehr Ahnung von Java, Joda und Konsorten hätte ...

        Was ich brauche ist was, wie das:
        Code:
        var DateTime sunrise = parse(year+"-"+month+"-"+day+"T"+Sunrise_Time.state) // Variable „Sunrise_Time“
        var DateTime wakeup = parse(year+"-"+month+"-"+day+"T"+sq_alarm_time.state) // Variable „sq_alarm_time“
        var DateTime now = now()
        
        if ( sunrise.isAfter(now) && wakeup.isAfter(now) ) {
          sendCommand(Rollos, UP)
        }
        Das wird aber so nicht funktioneren, da ich überhaupt keine Ahnung habe, ob ich hier Java-Müll geschrieben habe. Jedenfalls scheint es die Methoden now() und isAfter() zu geben und irgendwie sowas brauche ich.

        Ein Experte hat das vermutlich in 2 Minuten geschrieben. Ich brauche dafür vermutlich 2 Wochen (Try and Error) und dann geht irgendwas, ohne es verstanden zu haben :-(

        Jede Hilfe ist willkommen ...

        Danke schon mal und viele Grüße
        Michael

        Schön wäre, wenn openHAB eine einfache API bringen könnte, die solche Zeitoperationen mitbringt, so ala Excel. Zeiten vergleichen, Zeiten subtrahieren oder addieren, etc.

        Kommentar


          #5
          Hallo,
          ich würde es über einen Timer lösen.
          Du willst also die Zeit festlegen, wann die Rollos hochfahren.
          Das ist entweder die Sonnenaufgangszeit oder deine Weckzeit, wenn diese nach Sonnenaufgang ist.
          Am besten so gg. 4 Uhr ausführen lassen, dann gibt es auch keine Probleme mit der Umstellung Sommer/Winterzeit


          Code:
          // Import, bin mir nicht sicher ob man die alle braucht:
          import java.util.Date
          import java.util.TimeZone
          import java.text.SimpleDateFormat
          import org.joda.time.*
          
          //Sonnenaufgangszeit holen (bei mir wunderground)
          // Items:
          String  strSunrise       { http="<[http://api.wunderground.com/api/3f7804104c56181a/astronomy/q/DL/Leipzig.xml:600000:XSLT(wunderground_sunrise.xsl)]" }
          
          //Rules:
          rule "Rollo hoch"
          when    Time cron "0 0 4 * * ?"     //  4:00 Uhr
          then
              var DateTime sunrise
              var Integer akt_minuten
              var Integer sunrise_minuten
              var Integer weck_minuten
              var Integer warte_minuten
          
              //Stunde und Minute herausparsen:   
              sunrise  = parse("T"+strSunrise.state)    
          
              // Sonnenaufgang in Minuten nach Mitternacht   
              sunrise_minuten =  (sunrise.getHourOfDay * 60) + sunrise.getMinuteOfHour
          
              // wecken um 5:30 in Minuten nach Mitternacht   
              weck_minuten =  (5 * 60) + 30
              
              // aktuelle Minute, Berechnung kann evtl entfallen wenn die Regel immer zur selben Zeit läuft 
              akt_minuten = (now.getHourOfDay() * 60) + now.getMinuteOfHour
          
          // Vergleich welche Zeit später ist und den Timer setzen, Differenz zur aktuellen Zeit
              if (weck_minuten > sunrise_minuten) warte_minuten = weck_minuten - akt_minuten
              else  warte_minuten = sunrise_minuten - akt_minuten
              
              createTimer(now.plusMinutes(warte_minuten)) [|
                      // rollo hoch
                  ]
          end
          Ich hab es mal in meine Regeln kopiert um zu sehen ob es grob funktioniert.
          Lass dir die Werte mal in das Log ausgeben um das zu prüfen

          Holger

          Kommentar


            #6
            interessanter ansatz, werd ich auch mal testen. auf jeden fall eleganter als mein gestöpsel von gestern

            Kommentar


              #7
              Hallo Holger,

              vielen Dank für Deine Hilfe.
              Der OH Designer motzt bei den Zeilen
              Code:
                  if (weck_minuten > sunrise_minuten) warte_minuten = weck_minuten - akt_minuten
                  else  warte_minuten = sunrise_minuten - akt_minuten
              Die Fehlermeldung:
              Code:
              Incompatible types. Expected java.lang.Integer or int but was
                 java.math.BigDecimal
              Müssen die Variablen anders definiert werden oder kann ich das ignorieren?

              Viele Grüße
              Michael

              Kommentar


                #8
                Versuch es mal so, ich hab es nicht im Designer gemacht.
                Holger

                Kommentar


                  #9
                  Habe es jetzt mal im Designer gemacht und die Werte explizit nochmal mit toInt auf Integer gesetzt.
                  Gleichzeitig noch eine Abfrage eingefügt ob der Wert größer als null ist, falls die Regel nach Sonnenaufgang ausgeführt wird.

                  Wo beziehst du die Weckzeit her, SetPoint ?
                  Hier wäre die Integration noch interessant und auch der Wochentag.

                  Holger

                  Code:
                  rule "Rollo hoch zum Sonnenaufgang, aber nicht vor der Weckzeit"
                  when    Time cron "0 0 4 * * ?"     //  4:00 Uhr
                  then
                      var DateTime sunrise    
                      var Integer akt_minuten
                      var Integer sunrise_minuten
                      var Integer weck_minuten
                      var Integer warte_minuten
                  
                      //Stunde und Minute herausparsen:   
                      sunrise  = parse("T"+strSunrise.state)    
                  
                      // Sonnenaufgang in Minuten nach Mitternacht   
                      sunrise_minuten =  (sunrise.getHourOfDay * 60) + sunrise.getMinuteOfHour
                          
                      // wecken um 5:30 in Minuten nach Mitternacht   
                      weck_minuten =  (5 * 60) + 30
                    
                      // aktuelle Minute, Berechnung kann evtl entfallen wenn die Regel immer zur selben Zeit läuft 
                      akt_minuten = (now.getHourOfDay() * 60) + now.getMinuteOfHour
                     
                  // Vergleich welche Zeit später ist und den Timer setzen, Differenz zur aktuellen Zeit
                      if (weck_minuten > sunrise_minuten) 
                          warte_minuten = weck_minuten.intValue - akt_minuten.intValue
                      else  
                          warte_minuten = sunrise_minuten.intValue - akt_minuten.intValue
                    
                      if (warte_minuten > 0)
                      {
                          createTimer(now.plusMinutes(warte_minuten)) [|
                              // rollo hoch
                          ]
                      }    
                  end

                  Kommentar


                    #10
                    Hi Holger,

                    das Skript habe ich schon mal in mein OH eingepflanzt. Mal sehen, was dabei rauskommt ;-)
                    Jetzt bräucht ich nur eine kleine Hilfe.
                    Meine Weckzeit hole ich per Skript von meiner Squeezebox.
                    Code:
                    DateTime    sq_alarm_time    "Weckzeit [%1$tT]"    <uhr>    (gPlayerSchlafzimmer)    { exec="<[/opt/usr//openhab/scripts/getAlarmTimes.pl:3600000:REGEX((.*?))]" }
                    Dabei kommt ein String raus, wie 06:15 und zwar nur an Wochentagen. Am Wochenende ist der Wecker natürlich aus ;-) und das perl-Skript liefert ein undef zurück.

                    Wie bekomme ich diesen String in Stunden und Minuten zerpflückt, um die Minuten seit Mitternacht zu errechnen?

                    Kommentar


                      #11
                      Das ist ja schon ein DateTime.
                      Versuch mal ein sq_alarm_time.getHourOfDay

                      Holger

                      Kommentar


                        #12
                        Hi Holger,

                        das Skript hat Fehler geworfen:
                        Code:
                        04:00:00.229 ERROR o.o.m.r.i.e.ExecuteRuleJob[:57]- Error during the execution of rule Rollo hoch
                        java.lang.IllegalArgumentException: Invalid format: "T2014-07-11T05:23:00" is malformed at "14-07-11T05:23:00"
                                at org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:873)
                                at org.joda.time.DateTime.parse(DateTime.java:144)
                                at org.joda.time.DateTime.parse(DateTime.java:133)
                                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
                                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                        Ich vermute mal den Fehler in der Zeile
                        Code:
                        sunrise  = parse("T"+Sunrise_Time.state)
                        Wie funktionert denn diese Methode parse?

                        Viele Grüße
                        Michael

                        Kommentar


                          #13
                          Hallo, versuche es mal ohne das T am Anfang.
                          Von Wunderground hole ich mir nur die Uhrzeit.
                          Holger

                          Kommentar

                          Lädt...
                          X