Ankündigung

Einklappen
Keine Ankündigung bisher.

Berechnung Feiertage

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

    #16
    Hallo,

    klasse Arbeit. Habe das Prinzip noch um die Ferien in NRW ergänzt. Abhängig von "nicht Ferien" und "nicht Feiertag" werden wir zukünftig per Musik geweckt.

    Einfach folgende holiday.items ergänzen
    Code:
    Switch SchoolVacation			"Schulferien"
    String SchoolVacationName		"Schulferien [%s]"
    und das holiday.script auch um folgende Zeilen ergänzen (für NRW stimmen die Daten. Andere Bundesländer bitte anpassen):
    Code:
    var boolean schoolvac = false
    var String schoolvacName = null
    
    // NRW Daten von http://www.schulferien.org/NRW/nrw.html
    if (year == 2013) {
    	if (dayOfYear >= parse(year+"-12-21").getDayOfYear && 
    		dayOfYear <= parse(year+"-12-31").getDayOfYear) {
    		schoolvacName = "Weihnachtsferien"
    		schoolvac = true
    	}
    }
    
    if (year == 2014) {
    	if (dayOfYear >= parse(year+"-01-01").getDayOfYear && 
    		dayOfYear <= parse(year+"-01-07").getDayOfYear	) {
    		schoolvacName = "Weihnachtsferien"
    		schoolvac = true
    	} else if (dayOfYear >= parse(year+"-04-14").getDayOfYear && 
    		dayOfYear <= parse(year+"-04-26").getDayOfYear	) {
    		schoolvacName = "Osternferien"
    		schoolvac = true
    	} else if (dayOfYear == parse(year+"-06-10").getDayOfYear ) {
    		schoolvacName = "Pfingstferien"
    		schoolvac = true
    	} else if (dayOfYear >= parse(year+"-07-07").getDayOfYear && 
    		dayOfYear <= parse(year+"-08-19").getDayOfYear	) {
    		schoolvacName = "Sommerferien"
    		schoolvac = true
    	} else if (dayOfYear >= parse(year+"-10-06").getDayOfYear && 
    		dayOfYear <= parse(year+"-10-18").getDayOfYear	) {
    		schoolvacName = "Herbstferien"
    		schoolvac = true
    	} else if (dayOfYear >= parse(year+"-12-22").getDayOfYear&& 
    		dayOfYear <= parse(year+"-12-31").getDayOfYear) {
    		schoolvacName = "Weihnachtsferien"
    		schoolvac = true
    	}
    }
    
    if (year == 2015) {
    	if (dayOfYear >= parse(year+"-01-01").getDayOfYear && 
    		dayOfYear <= parse(year+"-01-06").getDayOfYear	) {
    		schoolvacName = "Weihnachtsferien"
    		schoolvac = true
    	} else if (dayOfYear >= parse(year+"-04-14").getDayOfYear && 
    		dayOfYear <= parse(year+"-04-26").getDayOfYear	) {
    		schoolvacName = "Osternferien"
    		schoolvac = true
    	} else if (dayOfYear == parse(year+"-05-26").getDayOfYear ) {
    		schoolvacName = "Pfingstferien"
    		schoolvac = true
    	} else if (dayOfYear >= parse(year+"-06-29").getDayOfYear && 
    		dayOfYear <= parse(year+"-08-11").getDayOfYear	) {
    		schoolvacName = "Sommerferien"
    		schoolvac = true
    	} else if (dayOfYear >= parse(year+"-10-05").getDayOfYear && 
    		dayOfYear <= parse(year+"-10-17").getDayOfYear	) {
    		schoolvacName = "Herbstferien"
    		schoolvac = true
    	} else if (dayOfYear >= parse(year+"-12-23").getDayOfYear&& 
    		dayOfYear <= parse(year+"-12-31").getDayOfYear) {
    		schoolvacName = "Weihnachtsferien"
    		schoolvac = true
    	}
    }
    
    if (year == 2016) {
    	if (dayOfYear >= parse(year+"-01-01").getDayOfYear && 
    		dayOfYear <= parse(year+"-01-06").getDayOfYear	) {
    		schoolvacName = "Weihnachtsferien"
    		schoolvac = true
    	} else if (dayOfYear >= parse(year+"-03-30").getDayOfYear && 
    		dayOfYear <= parse(year+"-04-11").getDayOfYear	) {
    		schoolvacName = "Osternferien"
    		schoolvac = true
    	} else if (dayOfYear == parse(year+"-05-17").getDayOfYear ) {
    		schoolvacName = "Pfingstferien"
    		schoolvac = true
    	} else if (dayOfYear >= parse(year+"-07-11").getDayOfYear && 
    		dayOfYear <= parse(year+"-08-23").getDayOfYear	) {
    		schoolvacName = "Sommerferien"
    		schoolvac = true
    	} else if (dayOfYear >= parse(year+"-10-10").getDayOfYear && 
    		dayOfYear <= parse(year+"-10-21").getDayOfYear	) {
    		schoolvacName = "Herbstferien"
    		schoolvac = true
    	} else if (dayOfYear >= parse(year+"-12-23").getDayOfYear&& 
    		dayOfYear <= parse(year+"-12-31").getDayOfYear) {
    		schoolvacName = "Weihnachtsferien"
    		schoolvac = true
    	}
    }
    
    if (schoolvacName!=null) {
        sendCommand(SchoolVacationName,schoolvacName)
    } else {
        sendCommand(SchoolVacationName,"")	
    }
    if (schoolvac) {
        postUpdate(SchoolVacation,ON)
    } else {
        postUpdate(SchoolVacation,OFF)
    }
    eine alarm.rules kann so aus sehen:
    Code:
    rule "Alarm off in Schulfreien und an Feiertagen"
    when
    	Item Holiday changed or
    	Item SchoolVacation changed
    then
    	if (Holiday.state == ON || SchoolVacation.state == ON) {
    		sendCommand(Alarm, OFF)
    	} else {
    		sendCommand(Alarm, ON)
    	}
    end
    
    
    rule "Wecker Montag-Freitag und nicht an Feiertagen/Schulferien"
    when
        Time cron "0 * * ? * MON,TUE,WED,THU,FRI"
    then
    	if (Anwesend.state == ON && Alarm.state == ON) {
        	var Integer sollMinute = (Alarm_Minute.state as DecimalType).intValue
         	var Integer sollStunde = (Alarm_Stunde.state as DecimalType).intValue
          	var Integer istMinute  = now.getMinuteOfHour()
          	var Integer istStunde  = now.getHourOfDay()
    
    		var Integer sollMinuteOfDay = sollStunde * 60 + sollMinute
    		var Integer istMinuteOfDay = istStunde * 60 + istMinute
    
          	if (sollMinuteOfDay == istMinuteOfDay)  {
    / ...
    	}
    end
    Viele Grüße
    Ralf

    Kommentar


      #17
      Hallo,

      hat jemand eine Idee, wie man den Tag vor einem Feiertag auf einen Switch legen kann. Hintergrund: Am Tag vor Karfreitag soll z.B. die Heizung später runterfahren etc. Über einen Tipp wäre ich sehr dankbar.

      Viele Grüße
      Hartmut

      Kommentar


        #18
        Wenn Du die Feiertagsberechnung schon aktiv hast (siehe holidays.script im 3. Posting dieses Threads), ist es das einfachste, dort eine zusätzliche Bedingung einzupflegen (also eastersunday.getDayOfYear-3) und dort direkt im Script den Schalter umzulegen. Dort, wo das Script aufgerufen wird, prüfst Du vor dem Aufruf des Scripts, ob der Schalter aktiv ist und schaltest ihn gegebenenfalls aus.
        das Script wird einmal täglich (0 Uhr) aufgerufen, bzw. wenn openHAB startet. Damit wird der Schalter täglich aktualisiert.
        Zuletzt geändert von udo1toni; 01.04.2018, 04:41.

        Kommentar


          #19
          Vielen Dank für die konkrete und schnelle Antwort. Allerdings würde ich gerne zwischen dem eigentlichen Feiertag und dem Tag vor dem Feiertag mittels eines virtuellen Schalters unterscheiden können. Es gibt - vermutlich geht das anderen auch so - unterschiedliche Anwendungsfälle für den eigentlichen Feiertag wie z.B. Heizung schaltet später ein, da man ausschläft und am Abend vorher geht as Licht später aus, da man länger auf ist, etc.

          Kommentar


            #20
            Naja, das geht entsprechend, indem Du über einen Schalter entscheidest, auf welchen Trigger eine Rule reagieren soll.
            Bisher gibt es leider kein Feiertag Binding, in welchem dann eventuell auch noch ein Offset definiert werden könnte (analog zum Astro Binding). Deshalb musst Du im Script, welches die Feiertage berechnet, für jeden Zeitpunkt, den Du verwenden willst, auch in irgendeiner Form einen Marker setzen. Du kannst z.B. auch ein Number Item einführen, was genau an Ostersonntag (des aktuellen Jahres) 0 ist. Davor ist es dann negativ, danach positiv. Dann musst Du halt wissen, dass Karfreitag -2 und der Tag vor Karfreitag -3 ist. Wenn das für alle Feiertage funktionieren soll, wäre vielleicht ein Item tagVorFeiertag nützlich, aber gesetzt werden muss es vom Script, also mit fast der doppelten Anzahl von if-Blöcken (Ostermontag, Pfingsmontag und 2. Weihnachtsfeiertag folgen ja einem Feiertag, der ohnehin schon bererchnet wird).

            Um in der Rule unterschiedlich zu reagieren, musst Du halt Bedingungen für den Schalter und die beteiligten Items einführen, also zum Beispiel so:
            Code:
            var Timer myTimer = null
            
            rule "Demo Feiertagsoffset"
            when
                Time cron "0 0 6 * * ?" //täglich 6 Uhr
            then
                myTimer.cancel
                myTimer = createTimer(now.plusSeconds(5), [|  //willkürliche Wartezeit, müsste man ausprobieren, ob vielleicht auch z.B. 50 Millisekunden reichen
                    Heizung.sendCommand(ON)
                    Kaffeemaschine.sendCommand(ON)
                    // Tu, was auch immer getan werden soll
                    myTimer = null
                ])
                if (feiertag.state == ON || ((ostern.state as Number) = -3 && offset.state == ON)) {
                    myTimer.reschedule(now.plusMinutes(60))
                }
            end
            Die Idee ist also, ein paar Sekunden vor dem frühesten eigentlichen Schalttermin einen Timer zu setzen, der dann die Schaltungen vornimmt. Anschließend wird geschaut, ob der Vorgang verzögert werden soll, falls das der Fall ist, wird der Timer neu geplant.
            Der Witz dabei ist, dass zum einen die Rule nur einmal ausgeführt wird, und zum anderen auch keine zusätzliche Last auftritt. Der Code wird als Lambda im Speicher abgelegt und zur geplanten Zeit ausgeführt, unabhängig davon, ob nun Feiertag ist oder nicht.
            Weiterhin muss der aktive Code nur einmal angelegt werden.
            Im if-Bereich der Rule können beliebig viele Bedingungne angegeben werden, die auch zu beliebigen (unterschiedlichen) Verzögerungen führen dürfen. Man könnte z.B. Samstags 30 Minuten und Sonntags 60 Minuten einplanen.
            Wenn man früher aufwacht und den Schalter umlegt, muss eine zweite Rule dafür sorgen, dass geprüft wird, ob der Timer bereits läuft (myTimer !== null) und dann gegebenenfalls den Timer mit .reschedule(now.plusSeconds(1)) neu planen, damit die entsprechenden Befehle schnellstmöglich ausgeführt werden. Wenn der Timer nicht läuft, ist es entweder (im Beispiel) vor 6 Uhr, oder schon nach 7 Uhr, damit spielt die Schalterstellung dann an diesem Tag keine Rolle.

            Kommentar


              #21
              Als Alternative:
              Nehme ein zweites (identisches) Script, in welchem Du die Angabe
              Code:
              var int dayOfYear = now.getDayOfYear
              durch
              Code:
              var int dayOfYear = now.getDayOfYear + 1
              ersetzt.
              Dann berechnest Du die Feiertage für den nächsten Tag und kannst einen zusätzlichen Schalter "DayBeforeHoliday" setzen.
              Ob der Tag selbst ein Feiertag ist, also z.B. in der Kombination Ostersonntag/Ostermontag spielt ja eigentlich keine Rolle...

              Oder Du setzt die Feiertagsabfragen in eine zusätzliche Schleife, die einmal für das heutige Datum und einmal für das morgige Datum durchlaufen wird. Das Ergebnis musst Du dann halt entsprechend als heutiger bzw. morgiger Feiertag verarbeiten.
              Der Vorteil ist, dass es nur eine Liste gibt, die angepasst/gepflegt werden muss, dafür ist die Logik ein bisschen schwieriger zu durchschauen...

              Andreas

              Kommentar

              Lädt...
              X