Feiertagsberechnung - Skript

Problemlösungen und Hinweise von allgemeinem Interesse zur Haussteuerung mit HomeMatic

Moderator: Co-Administratoren

Petrus
Beiträge: 134
Registriert: 13.01.2010, 20:53
Hat sich bedankt: 1 Mal
Danksagung erhalten: 25 Mal

Re: Feiertagsberechnung - Skript

Beitrag von Petrus » 06.08.2018, 15:35

Kerschten hat geschrieben:
04.08.2018, 13:06
...Hast du einen Tipp für mich? Habe auch schon versucht die SV mit einem Skript zu füllen, aber auch das gelingt mir leider nicht.
Hallo Kerschten,

da die Frage bzgl. des Variablentyps nun schon des Öfteren gestellt wurde, habe ich die Skripte (Compact und Complete) so angepasst, dass jetzt beide Typen - Zeichenkette und Werteliste - ausgewertet werden. Im Complete-Script wird die SV zwar bei Bedarf weiterhin automatisch als Zeichenkette angelegt, aber in der CCU ist der Typ ja schnell geändert.

Ich habe die beiden geänderten Skripte mal angehängt. Da ich sie selbst noch nicht testen konnte, bitte ich um Rückmeldung ob es funktioniert. Bei Erfolgsmeldungen würde ich die beiden Skripte dann in den 1. Post verschieben.

Gruß
Petrus

Erledigt: Skripte wurden erfolgreich getestet und dem 1.Post ( Hier ) hinzugefügt.

Benutzeravatar
dogfight76
Beiträge: 322
Registriert: 27.08.2014, 16:26
Hat sich bedankt: 12 Mal
Danksagung erhalten: 1 Mal

Re: Feiertagsberechnung - Skript

Beitrag von dogfight76 » 23.09.2018, 09:46

Hallo,

habe auch das neue Script entdeckt. (Nutze noch das alte)

Jetzt verstehe ich einige Sachen in der Anleitung nicht.
Wo kann im Code (welche Zeile) finde ich die "Scriptvariable Nr. 4" ?
So das ich sie einmal durchlaufen lassen kann.

Erstmal soweit........

Gruß

EDIT: Das mit den SV habe ich nach ca. 100 lesen verstanden "Urlaub" und "kein Urlaub" ist jeweils eine SV
Zuletzt geändert von dogfight76 am 23.09.2018, 10:38, insgesamt 4-mal geändert.
RaspberryMatic CCU3 mit aktueller FW

Benutzeravatar
dogfight76
Beiträge: 322
Registriert: 27.08.2014, 16:26
Hat sich bedankt: 12 Mal
Danksagung erhalten: 1 Mal

Re: Feiertagsberechnung - Skript

Beitrag von dogfight76 » 23.09.2018, 10:04

Das hier ist das Script was ich momentan nutze:

Code: Alles auswählen

! Urlaub
! 

! *************************************************************************
! Es werden nachfolgende Systemvariablen benoetigt.

! 1. Systemvariable  Name: Arbeitstag_heute
!                     Typ: Logikwert

! 2. Systemvariable  Name: Arbeitstag_morgen
!                     Typ: Logikwert

! 3. Systemvariable  Name: Urlaubstage
!                     Typ: Werteliste

! Die Werte (Urlaubsdaten) in der 3. Systemvariablen muessen wie folgt formatiert sein:

!      Urlaubstag: XX.XX. (Bsp. 12.04.)
! Urlaubszeitraum: XX.XX.-XX.XX. (Bsp. 23.12.-06.01.)

! Zahlenwerte immer 2-stellig angeben. (Falsch: 3.2. Richtig: 03.02.)
! Als Trennzeichen zwischen den Daten ist das Semikolon anzuwenden.
! Zum Beispiel: "02.02.;15.05.;20.12.-05.01."

! Wichtig!!!
! Vor einem Jahreswechsel sollten alle alten Urlaubsdaten gelöscht werden.
! Im Beispiel oben wären das der "02.02." und der "15.05."
! *************************************************************************


string uTage = dom.GetObject('Urlaubstage').ValueList();   !Datumswerte aus der SV auslesen
boolean Arbeitstag_heute = true;   ! Wird false, wenn heute ein Urlaubstag ist
boolean Arbeitstag_morgen = true;  ! Wird false, wenn morgen ein Urlaubstag ist
  
if (uTage.Length() >= 6) { ! Verarbeitung nur beginnen, wenn Urlaubsdaten hinterlegt sind.

  string Zahlen = "0,1,2,3,4,5,6,7,8,9";    ! Wird fuer die Ueberpruefung des Datumsformates benoetigt
  string Datumsformat = "XX.XX.-XX.XX.";    ! Das Datumsformat fuer die Ueberpruefung

  integer Tag_heute = system.Date("%d").ToInteger();    ! Die Tageszahl des heutigen Datums
  integer Monat_heute = system.Date("%m").ToInteger();  ! Die Monatszahl des heutigen Datums
  integer Jahr = system.Date("%Y").ToInteger();         ! Die aktuelle Jahreszahl

  ! **************************************
  ! **** Das morgige Datum ermitteln! ****
  ! **************************************

  if ((Jahr % 4) == 0) { ! Ein Schaltjahr -> Feb. = 29 Tage
	string mTage = "31,29,31,30,31,30,31,31,30,31,30,31"; ! Anzahl der Tage im Monat Jan.-Dez.
  } else {
	string mTage = "31,28,31,30,31,30,31,31,30,31,30,31"; ! Anzahl der Tage im Monat Jan.-Dez.
  }
 
  ! Anzahl der Tage im aktuellen Monat
  integer TageMonat = mTage.Substr(((3 * Monat_heute) - 3), 2).ToInteger();
  integer Tag_morgen = Tag_heute + 1;
  integer Monat_morgen = Monat_heute;

  ! Pruefen ob morgen ein Monatswechsel vorliegt  
  if (Tag_morgen > TageMonat) {
    Tag_morgen = 1;
    if (Monat_heute == 12) { Monat_morgen = 1; } else { Monat_morgen = Monat_heute + 1; }
  }
  
  boolean Pruefen = true;
  string uDatum;	
  foreach(uDatum, uTage.Split(";")) {

    if (Pruefen) { ! Wenn kein Urlaubstag gefunden wurde oder die restlichen Daten nicht in der Zukunft liegen, weiter pruefen...

        ! ************************************************************************************
        ! **** Zunaechst wird die korrekte Formatierung des hinterlegten Datums geprueft! ****
        ! ************************************************************************************
		
        integer dLaenge = uDatum.Length();
        integer zPos = 0;
        boolean dFormat = true;
        while (zPos < dLaenge) {
            if (((dLaenge == 6) || (dLaenge == 13)) && (dFormat)) {
                if (Datumsformat.Substr(zPos, 1) == "X") {
                    string dZahl;
                    boolean Ziffer = false;
                    foreach(dZahl, Zahlen.Split(",")) { if (uDatum.Substr(zPos, 1) == dZahl) { Ziffer = true; } }
                    if (!Ziffer) { dFormat = false; }
                } else {
                    if (uDatum.Substr(zPos, 1) <> Datumsformat.Substr(zPos, 1)) { dFormat = false; }
                }
            } else {
                dFormat = false;
            }
            zPos = zPos + 1;
        }

        ! ***********************************************************************************************
        ! **** Wenn das Datum korrekt formatiert ist (dFormat = true), wird geprueft, ob eine        ****
        ! **** Uebereinstimmung mit dem heutigen und/oder morgigen Datum vorliegt => kein Arbeitstag ****
        ! ***********************************************************************************************

        if (dFormat) {
            integer StartTag = uDatum.Substr(0, 2).ToInteger();   ! Die Tageszahl des 1. Urlaubstages
            integer StartMonat = uDatum.Substr(3, 2).ToInteger(); ! Die Monatszahl des 1. Urlaubstages
            integer Durchlauf = 1;
            integer Tag = Tag_heute;
            integer Monat = Monat_heute;
			
            while (Durchlauf <= 2) { ! Insgesamt 2 Durchlaeufe für Datum heute und morgen...

              if (Durchlauf == 2) {
                Tag = Tag_morgen;
                Monat = Monat_morgen;
              }
			  
              if ((Tag == StartTag) && (Monat == StartMonat)) {
                  if (Durchlauf == 1) {
                    Arbeitstag_heute = false;
                  } else {
                      Arbeitstag_morgen = false;
                      Pruefen = false; ! Ueberpruefung beenden, da zukuenftige Daten nicht interessieren.
                  }
              } else {
                  integer EndTag = uDatum.Substr(7, 2).ToInteger();    ! Die Tageszahl des letzten Urlaubstages
                  integer EndMonat = uDatum.Substr(10, 2).ToInteger(); ! Die Monatszahl des letzten Urlaubstages

                  if ((Durchlauf == 2) && (((Tag < StartTag) && (Monat == StartMonat)) || ((Monat < StartMonat) && (StartMonat < EndMonat)))) { ! Wenn das Urlaubsdatum in der Zukunft liegt...
                      Pruefen = false; ! ...Ueberpruefung beenden.
                  } else {
                      if (dLaenge > 6) { ! Ist ein Urlaubszeitraum angegeben?
                          if (EndMonat < StartMonat) { ! Wenn sich Zeitraum ueber die Jahresgrenze erstreckt...  

                              ! ...pruefen, ob Startdatum <= Datum heute <= 31.12. oder Datum heute <= Enddatum
                              if (((((Tag >= StartTag) && (Monat == StartMonat)) || (Monat > StartMonat)) && ((Tag <= 31) && (Monat == 12))) || ((Tag <= EndTag) && (Monat <= EndMonat))) {
                                  if (Durchlauf == 1) {
                                    Arbeitstag_heute = false;
                                  } else {
                                      Arbeitstag_morgen = false;
                                      Pruefen = false; ! Ueberpruefung beenden, da zukuenftige Daten nicht interessieren.
                                  }
                              }
                          } else { ! Wenn Zeitraum nicht ueber Jahresgrenze geht,...

                              ! ...dann pruefen, ob Startdatum <= Datum heute <= Enddatum
                              if ((((Tag >= StartTag) && (Monat == StartMonat)) || (Monat > StartMonat)) && (((Tag <= EndTag) && (Monat == EndMonat)) || (Monat < EndMonat))) {
                                  if (Durchlauf == 1) {
                                    Arbeitstag_heute = false;
                                  } else {
                                      Arbeitstag_morgen = false;
                                      Pruefen = false; ! Ueberpruefung beenden, da zukuenftige Daten nicht interessieren.
                                  }
                              }
                          }
                      }
                  }
              }
              Durchlauf = Durchlauf + 1;
            }
        } else { ! Wenn Fehler im Datumsformat => Eintrag ins Log
            system.Exec("logger -t script -p user.debug Formatierungsfehler in Urlaubstage: " # uDatum);
        }
    }
  }
}

dom.GetObject('Arbeitstag_heute').State(Arbeitstag_heute);
dom.GetObject('Arbeitstag_morgen').State(Arbeitstag_morgen);

Ich benötige also mit dem neuen die beiden SV "Arbeitstag_heute" und "Arbeitstag_morgen" nicht mehr. Und könnte das Script im alten Programm doch einfach duch den neuen Script-Code ersetzen, korrekt ?

Gruß
RaspberryMatic CCU3 mit aktueller FW

Petrus
Beiträge: 134
Registriert: 13.01.2010, 20:53
Hat sich bedankt: 1 Mal
Danksagung erhalten: 25 Mal

Re: Feiertagsberechnung - Skript

Beitrag von Petrus » 23.09.2018, 12:05

Hallo,

wie bereits einige Posts vorher schon beschrieben, gehe wie folgt vor:
  1. In der CCU unter "Programme und Verknüpfungen" -> "Programme und Zentralenverknüpfungen" -> "Skript testen" das Skript "Urlaubstage - complete" einfügen.
  2. Im Code b_debug=true sowie b_CheckSVs=true setzen und dann auf "Ausführen" klicken. Unter Ausgabe bekommst du die Bestätigungen über die automatisch angelegten SVs.
  3. Jetzt kannst du ein neues Programm erstellen - oder auch dein bereits vorhandenes weiter nutzen - und fügst als Skript das "Urlaubstage - compact" ein.

Hinweis zur Eingabe der Urlaubsdaten:

Die Systemvariable "Urlaubstage" wird automatisch als "Zeichenkette" deklariert. Dies ist sinnvoll, wenn man Apps, wie z.B. PocketControl, verwendet und dort die Urlaubsdaten eingeben möchte.
Wenn man aber, wie beim alten Skript, weiterhin zur Eingabe der Urlaubsdaten die WebUI nutzen möchte, dann muss man in der CCU den Typ der SV "Urlaubstage" auf "Werteliste" ändern.

Viele Grüße
Petrus

Benutzeravatar
dogfight76
Beiträge: 322
Registriert: 27.08.2014, 16:26
Hat sich bedankt: 12 Mal
Danksagung erhalten: 1 Mal

Re: Feiertagsberechnung - Skript

Beitrag von dogfight76 » 23.09.2018, 13:44

Wo im Code sind die beiden Einträge ? Finde sie nicht.....kannst mir die Zeilen nennen ?

Gruß
RaspberryMatic CCU3 mit aktueller FW

Petrus
Beiträge: 134
Registriert: 13.01.2010, 20:53
Hat sich bedankt: 1 Mal
Danksagung erhalten: 25 Mal

Re: Feiertagsberechnung - Skript

Beitrag von Petrus » 23.09.2018, 16:11

Zeilen 63 und 65. Dort die Werte von false auf true setzen.

Benutzeravatar
dogfight76
Beiträge: 322
Registriert: 27.08.2014, 16:26
Hat sich bedankt: 12 Mal
Danksagung erhalten: 1 Mal

Re: Feiertagsberechnung - Skript

Beitrag von dogfight76 » 23.09.2018, 17:16

Danke, gefunden ! Und Urlaub über PocketControl eingetragen !
RaspberryMatic CCU3 mit aktueller FW

Benutzeravatar
dogfight76
Beiträge: 322
Registriert: 27.08.2014, 16:26
Hat sich bedankt: 12 Mal
Danksagung erhalten: 1 Mal

Re: Feiertagsberechnung - Skript

Beitrag von dogfight76 » 23.09.2018, 17:31

Jetzt zu den Feiertagen, auch da nutze ich bisher altes Script.

Habe ich genauso gemacht, die Feiertagsliste mit DE und NI (weil Niedersachsen) geteset. SV wurden angelegt und dann das Script "compact" in meinem vorhandenem Programm ersetzt. Die SV in den weiterführenden Programmen ersetzt.

Schon fertig, richtig ?

Ist denn der 31.Oktober schon eingepfelgt als Feiertag für NI ?

Gruß
RaspberryMatic CCU3 mit aktueller FW

Petrus
Beiträge: 134
Registriert: 13.01.2010, 20:53
Hat sich bedankt: 1 Mal
Danksagung erhalten: 25 Mal

Re: Feiertagsberechnung - Skript

Beitrag von Petrus » 23.09.2018, 22:12

Jap, vorgehensweise analog zum Urlaubsscript. Einzig die Erstellung der individuellen Feiertagsliste muss einmal durchgeführt werden.

Der Reformationstag (31.10.) ist noch nicht enthalten. Dieser Feiertag wurde - soweit ich da richtig liege - auch erst im Juni 2018 in NI zum gesetzlichen Feiertag. Muss ich im Skript "Feiertagsliste" noch ändern.

Dafür kannst du die SV Feiertag-Eigene nutzen und um den Eintrag 31.10.=Reformationstag ergänzen.

Gruß
Petrus

Benutzeravatar
dogfight76
Beiträge: 322
Registriert: 27.08.2014, 16:26
Hat sich bedankt: 12 Mal
Danksagung erhalten: 1 Mal

Re: Feiertagsberechnung - Skript

Beitrag von dogfight76 » 24.09.2018, 10:03

Da es eine Zeichenkette ist geht das manuelle Nachtragen von Feiertagen auch über die App "Pocket Control" und nicht über das WebIF, richtig ?

Gruß
RaspberryMatic CCU3 mit aktueller FW

Antworten

Zurück zu „HomeMatic Tipps & Tricks - keine Fragen!“