Feiertagsberechnung - Skript

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

Moderator: Co-Administratoren

Rupertus
Beiträge: 12
Registriert: 15.01.2017, 19:58

Re: Feiertagsberechnung - Skript

Beitrag von Rupertus » 27.03.2017, 19:11

Vielleicht stehe ich ja auf dem Schlauch, aber welches Script auf Seite 1 meinst Du? Beim Urlaubsscript v3.01 habe ich keine Systemvariable "Urlaub_morgen" die ich abfragen könnte. Da gibt es doch nur "Arbeitstag_heute", "Arbeitstag_morgen" und "Urlaubstage". Wie hast Du es umgesetzt, dass die Lichter am Abend länger anbleiben, wenn man am nächsten Tag frei hat, also "Urlaub_morgen"?

Cash
Beiträge: 1184
Registriert: 09.01.2016, 17:42
Wohnort: Sauerland
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal

Re: Feiertagsberechnung - Skript

Beitrag von Cash » 27.03.2017, 21:28

Wenn Arbeitstag Morgen falsch was ist dann wohl Morgen? Man könnte es Urlaub nennen oder?

Ich muss aber gestehen das ich das Script etwas angepasst habe. Meine Variablen heißen Urlaub heute und Urlaub Morgen...

Ich habe also einfach die Variabeln umbenannt und das ursprüngliche wahr wurde zu falsch und das falsch zu wahr.

Ich fand es nämlich doof wenn die Variable Arbeitstag heute gleich wahr war es aber z. B. Sonntag ist und ich kein Arbeitstag habe :-)

Rupertus
Beiträge: 12
Registriert: 15.01.2017, 19:58

Re: Feiertagsberechnung - Skript

Beitrag von Rupertus » 27.03.2017, 22:27

Ja, danke. Das ist ein Ansatz den ich, trotz meiner geringen Kenntnisse, mal versuchen könnte umzusetzen. Oder würdest Du mir Dein angepasstes Script zu Verfügung stellen?

Cash
Beiträge: 1184
Registriert: 09.01.2016, 17:42
Wohnort: Sauerland
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal

Re: Feiertagsberechnung - Skript

Beitrag von Cash » 28.03.2017, 09:01

Bitte beachten das Script habe ich in meiner Anfangszeit angepasst. Es ist Quick & Dirty. Wenn Du Probleme mit der 200 Script-Variablen Grenze hast solltest Du hier die ein oder andere Variable einsparen.

Meine Systemvariablen lauten alle "CCU SV..." oder "SV ..." entweder auch so nennen oder anpassen. Ich nutze auch Leerzeichen in den Systemvariablen.

Die Systemvariable "SV Urlaubstage" habe ich nicht wie ursprünglich als Werteliste angelegt sondern als Text. Werteliste hat den Nachteil das ich in den div. Apps fürs Smartphone die Urlaubstage nicht richtig pflegen konnte. Als Text gibt es hier keine Probleme. Das Script läuft einmalig Nachts...

Code: Alles auswählen

! Version 1.0 vom 16.02.2016
! Script V3.01 von Peter Beck - 11.2013
!  
! *************************************************************************
! Es werden nachfolgende Systemvariablen benoetigt.

! 1. Systemvariable  Name: SV Urlaub heute
!                     Typ: Logikwert

! 2. Systemvariable  Name: SV Urlaub morgen
!                     Typ: Logikwert

! 3. Systemvariable  Name: SV Urlaubstage
!                     Typ: Text

! 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('SV Urlaubstage').Variable();   !Datumswerte aus der SV auslesen
boolean Arbeitstag_heute = false;   ! Wird true, wenn heute ein Urlaubstag ist
boolean Arbeitstag_morgen = false;  ! Wird true, 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 = true;
                  } else {
                      Arbeitstag_morgen = true;
                      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 = true;
                                  } else {
                                      Arbeitstag_morgen = true;
                                      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 = true;
                                  } else {
                                      Arbeitstag_morgen = true;
                                      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('SV Urlaub heute').State(Arbeitstag_heute);
dom.GetObject('SV Urlaub morgen').State(Arbeitstag_morgen);

Rupertus
Beiträge: 12
Registriert: 15.01.2017, 19:58

Re: Feiertagsberechnung - Skript

Beitrag von Rupertus » 28.03.2017, 20:21

Prima. Danke für das Script. Das wird mir sicherlich weiterhelfen.
Auch danke an euch für das Posten der verschiedenen Lösungsansätze zu meinem Problem.

Rupertus
Beiträge: 12
Registriert: 15.01.2017, 19:58

Re: Feiertagsberechnung - Skript

Beitrag von Rupertus » 02.04.2017, 17:22

Hallo.

Ich wollte heute mal das Script einfügen, bemerke aber das ich keine Option habe eine Systemvariable mit dem Typ Text anzulegen. Nur Zeichenkette oder Werteliste. Eine Werteliste soll es nach deiner Beschreibung nicht sein. Eine Zeichenkette wäre ja vom Grunde her eigentlich auch ein Text, aber wie erhält die Variable dann die Urlaubstage? Wie hast du das gelöst?

Murmelbaerchen6903
Beiträge: 22
Registriert: 04.12.2016, 17:27

Re: Feiertagsberechnung - Skript

Beitrag von Murmelbaerchen6903 » 02.04.2017, 17:53

Rupertus hat geschrieben:Hallo.

Ich wollte heute mal das Script einfügen, bemerke aber das ich keine Option habe eine Systemvariable mit dem Typ Text anzulegen. Nur Zeichenkette oder Werteliste. Eine Werteliste soll es nach deiner Beschreibung nicht sein. Eine Zeichenkette wäre ja vom Grunde her eigentlich auch ein Text, aber wie erhält die Variable dann die Urlaubstage? Wie hast du das gelöst?
Hallo,

Zeichenkette ist ein Textfeld.

Gruß Ralf

Gesendet von meinem SM-N910F mit Tapatalk

Rupertus
Beiträge: 12
Registriert: 15.01.2017, 19:58

Re: Feiertagsberechnung - Skript

Beitrag von Rupertus » 02.04.2017, 19:51

Ok. Danke. Also so, wie ich es vermutet hatte. Da die Urlaubstage aber nicht mehr als Werteliste in die Systemvariable eingetragen werden, müssen die Urlaubstage irgenwo anders eingepflegt werden, damit die Zeichenkette ihre Werte erhält. Eventuell direkt im Script, aber an welcher Stelle?

Murmelbaerchen6903
Beiträge: 22
Registriert: 04.12.2016, 17:27

Re: Feiertagsberechnung - Skript

Beitrag von Murmelbaerchen6903 » 02.04.2017, 20:23

Einfach, in der SV eintragen. Es ging nur darum das SV vom Typ Zeichenkette von z.B. HomeDroid bearbeitet werden kann. Wenn du darauf keinen Wert legst, kannst du auch eine SV vom Typ Werteliste nehmen.

Gesendet von meinem SM-N910F mit Tapatalk

Rupertus
Beiträge: 12
Registriert: 15.01.2017, 19:58

Re: Feiertagsberechnung - Skript

Beitrag von Rupertus » 02.04.2017, 21:27

Vielleicht mache ich ja etwas falsch, aber stelle ich die SV auf Zeichenkette, kann ich dort nichts mehr eintragen.

Antworten

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