Feiertagsberechnung - Skript

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

Moderator: Co-Administratoren

Garbsen
Beiträge: 86
Registriert: 12.07.2017, 21:08

Re: Feiertagsberechnung - Skript

Beitrag von Garbsen » 09.02.2019, 22:03

@xel66:
Jup, jeder hat halt andere Präferenzen, ist ja gut so!
Alles was hier im Landkreis zur Verfügung steht ist ein iCal, der lediglich den regulären Rhythmus Abbilder (als wiederkehrender Termin) da müssen alle geplanten Abweichungen ohnehin manuell erfasst werden und die kurzfristig auftretenden natürlich sowieso, auch wenn der iCal die „vorhersehbaren“ enthalten würde
512 Kanäle in 101 Geräten und 145 CUxD-Kanäle in 19 CUxD-Geräten:
--------------------------------------------
http://www.eq-3.de/service/downloads.html
Tips und Tricks für Anfänger: viewtopic.php?t=22801
Programmlogik: viewtopic.php?f=31&t=4251
Webui-Handbuch: https://www.eq-3.de/Downloads/eq3/downl ... h_eQ-3.pdf
Script und Linksammlung: viewtopic.php?f=26&t=27907

Xel66
Beiträge: 5469
Registriert: 08.05.2013, 23:33
Wohnort: Nordwürttemberg
Hat sich bedankt: 1 Mal
Danksagung erhalten: 6 Mal

Re: Feiertagsberechnung - Skript

Beitrag von Xel66 » 09.02.2019, 22:25

Garbsen hat geschrieben:
09.02.2019, 22:03
... lediglich den regulären Rhythmus Abbilder (als wiederkehrender Termin) da müssen alle geplanten Abweichungen ohnehin manuell erfasst werden ...
Hmmm... Service sieht anders aus. Bei mir im Landkreis passt das. Aber das soll nicht das Thema hier sein. Für mich wäre es deutlich zu viel Aufwand, solche Daten manuell zu erfassen oder anzupassen. Der Kalenderimport ist deutlich einfacher zu handhaben und steht dann letztendlich allen Geräten mit Zugriff auf diesen Kalender zur Verfügung. Somit ist es auch möglich, ein und dieselben Daten auch am Tablet und am Smartphone anzuzeigen und ggf. Erinnerungen zu generieren. Datenerfassung auf der CCU ist dagegen nur für einen Zweck vorhanden und eigentlich eine datentechniche Sackgasse, weil sie nur dort zu nutzen sind. Aber BTT. Hier geht's ums Feiertagsscript und nicht um mögliche Alternativlösungen.

Gruß Xel66
---------------------------------------------------------------------------------
335 Kanäle in 103 Geräten und 113 CUxD-Kanäle in 23 CUxD-Geräten:
233 Programme, 189 Systemvariablen und 119 Direktverknüpfungen,
RaspberryMatic Version 3.45.5.20190330
---------------------------------------------------------------------------------

Petrus
Beiträge: 101
Registriert: 13.01.2010, 20:53

Re: Feiertagsberechnung - Skript

Beitrag von Petrus » 10.02.2019, 15:04

@Xel66
Xel66 hat geschrieben:
09.02.2019, 21:33
..Leider ist diese funktionale und kompakte Lösung zur eierlegenden Wollmilchsau aufgebohrt worden, deren vorrangige Zweck die "Anzeige" ist und nicht die Funktionaltät für die Automation. Aber jeder wie er will.
Naja, da bin ich nicht ganz bei dir. Es ist definitiv keine zur eierlegenden Wollmilchsau "aufgebohrte" Lösung. Es befriedigt weder alle Bedürfnisse, noch genügt es allen Ansprüchen. Soll es ja auch nicht! Es ist definitiv, wie die Ur-Version (die übrigens weiterhin im 1.Post zum Download zur Verfügung steht), eine funktionale und kompakte Lösung. Lediglich die Berechnung und Auswertung erfolgt auf einem anderen Weg. Das mit den Namen der Feiertage wird dabei ganz nebenbei erledigt, "ohne" den Code zusätzlich aufzublähen.
Die Gründe für diese Überarbeitung hatte ich bereits in der EInleitung im 1.Post beschrieben. Daraus kann man sicher ableiten, dass das Skript nicht dem vorrangigen Zweck der Anzeige dient, sondern eher der Funktionalität für die Automation.

Nur mal zur generellen Aufklärung!

@Garbsen
Garbsen hat geschrieben:
09.02.2019, 21:27
@Petrus:
Könnte man anstatt „Tage bis Urlaubsbeginn“ auch nach Tage bis Urlaubsende“ rechnen lassen? (oder eventuell beides)?
Welche Berechnung müsste ich da im Script anpassen?
Die Variablen im Skript haben folgende/n Bedeutung/Inhalt:
i_count : Tage bis zum Urlaubsbeginn
i_start : Der Jahrestag des 1. Urlaubstages
i_ende : Der Jahrestag des letzten Urlaubstages

Damit du also die Tage bis zum Urlaubsende ausgeben kannst, benötigst du das Ergebnis folgender Berechnung:
Tage bis Urlaubsende = i_count + i_ende - i_start

Solche persönlichen Anpassungen sind übrigens nur dadurch möglich, weil die Berechnungen - im Gegensatz zur Ur-Version - auf Jahrestage umgestellt wurden. :wink:

Viele Grüße
Petrus

Garbsen
Beiträge: 86
Registriert: 12.07.2017, 21:08

Re: Feiertagsberechnung - Skript

Beitrag von Garbsen » 10.02.2019, 22:08

Damit du also die Tage bis zum Urlaubsende ausgeben kannst, benötigst du das Ergebnis folgender Berechnung:
Tage bis Urlaubsende = i_count + i_ende - i_start
Zunächst Danke für jede Hilfestellung. Für Tage bis Urlaubsende benötigt es natürlich auf jeden Fall eine weitere Variable, fände ich jedenfalls besser, als die vorhandene Variable Tage bis Beginn zu ändern, so behält man Flexibilität.

Interessant finde ich eine solche Variable eigentlich nur für Urlaube, die in Zeiträumen angegeben sind, bei einzelnen Tagen macht es wenig Sinn (zumindest für meine Anwendung) und eigentlich auch nur während des laufenden Urlaubs (wie zuvor geschrieben, um gegebenenfalls die Heizung abhängig von der aktuellen Raumtemperatur 1,2, oder 3 Tage vorher hochzufahren)

Müsste ich dann nicht Tage bis Urlaubsende aus i_ende - i_today berechnen können? Denn i_start ist ja während des laufenden Urlaubs schon vorbei, oder kann (sollte) ich dann trotzdem damit rechnen?

Ich habe mich mal durch das Script durchgearbeitet, wirklich sehr lehrhaft! Ich finde es wahnsinnig spannend, wie du das alles sehr strukturiert und flexibel gehalten hast. Ich kann glaube ich ich von dem Script mehr über Script-Programmierung lernen als alles was ich bisher gesehen habe.

Ich habe mich mal daran versucht, die Änderungen auszuarbeiten, die notwendig wären, um eine zusätzliche Varible für Tage bis Urlaubsende zu erstellen und zu füllen.


Vielleicht kannst du mal drüber schauen

Code: Alles auswählen



string sv_count = "Urlaub-Tage-bis,Tage-bis-Urlaubsende";

  foreach(s_data1, sv_count.Split(",")) {
    svObj = svObjects.Get(s_data1);
    ! ***Wenn SV vorhanden => ValueTyp pruefen
    if (svObj) {
        if (svObj.ValueSubType() != ivtFloat) { WriteLine(s_data1 # " : ValueSubTyp wrong!"); quit; }
        else { if (b_debug) { WriteLine(s_data1 # " : ValueTyp OK!"); } }
    ! ***andernfalls SV neu anlegen
    } else {
        svObj = dom.CreateObject(OT_VARDP);
        svObjects.Add(svObj.ID());
        svObj.Name(s_data1);
        svObj.ValueType(ivtFloat);
        svObj.ValueSubType(istGeneric);
        svObj.ValueName0("Tage bis zum Urlaub");
        svObj.ValueName1("Tage-bis-Urlaubsende");
        svObj.ValueUnit("");
    	svObj.ValueMin(-1);
    	svObj.ValueMax(1000);
    	svObj.State(-1);
    	svObj.Internal(false);
    	svObj.Visible(true);
    	dom.RTUpdate(false);
        if (b_debug) { WriteLine(s_data1 # " : Systemvariable create!"); }
    }
  }



if (holydays) {
  ! *** Scriptvariablen
  boolean Urlaub_heute=false; boolean Urlaub_morgen=false; boolean pruefung=true;
  integer i_idx=0; integer i_data; integer i_today; integer i_count=-1; integer i_count2=-1; string holyday; string s_idx="";


if ((i_today >= i_start) && (i_today <= i_ende)) { Urlaub_heute = true; i_count=0; i_count2=i_ende-i_today} ! ...heute Urlaub und...

	svObj=svObjects.Get(sv_count.StrValueByIndex(",", 0)); if (svObj){svObj.State(i_count);}
    svObj=svObjects.Get(sv_count.StrValueByIndex(",", 1)); if (svObj){svObj.State(i_count2);}

Bleiben bei mir zumindest folgende Fragen:

Wie stelle ich sicher, dass die Variable nach Urlaubsende auf null geht und nicht unsinnig negativ wird (quasi Tage seit letztem Urlaub, wobei das ja auch interessant sein könnte ;-) )

Wie baue ich diese Variable in die Version „keine Zeiträume“ ein, wie gesagt, ist vermutlich ohnehin dafür nicht so wichtig, aber ich denke es macht Sinn, alles universell zu halten.

Vermutlich wäre es auch „sauberer“ i_count überall in i_count1 umzubenennen.


Gibt es noch andere Stellen, an denen ich etwas ändern/ergänzen muss?

Danke K-H
512 Kanäle in 101 Geräten und 145 CUxD-Kanäle in 19 CUxD-Geräten:
--------------------------------------------
http://www.eq-3.de/service/downloads.html
Tips und Tricks für Anfänger: viewtopic.php?t=22801
Programmlogik: viewtopic.php?f=31&t=4251
Webui-Handbuch: https://www.eq-3.de/Downloads/eq3/downl ... h_eQ-3.pdf
Script und Linksammlung: viewtopic.php?f=26&t=27907

Petrus
Beiträge: 101
Registriert: 13.01.2010, 20:53

Re: Feiertagsberechnung - Skript

Beitrag von Petrus » 11.02.2019, 13:32

Garbsen hat geschrieben:
10.02.2019, 22:08
Zunächst Danke für jede Hilfestellung...
Gerne geschehen. Ich helfe, wo ich kann!
Garbsen hat geschrieben:
10.02.2019, 22:08
...Ich habe mich mal durch das Script durchgearbeitet, wirklich sehr lehrhaft! Ich finde es wahnsinnig spannend, wie du das alles sehr strukturiert und flexibel gehalten hast. Ich kann glaube ich ich von dem Script mehr über Script-Programmierung lernen als alles was ich bisher gesehen habe.
Genau aus dem Grund biete ich das Complete-Skript an. Man lernt am besten, wenn man selbst viel ausprobiert und dabei über die Schulter der anderen schaut, wie die das gelöst haben. Oder einfach mittels Copy/Paste einzelne Passagen in ein eigenes Skript übernimmt, dort abändert um zu schauen, was passiert. Learning by doing.

Nun zu deinem Anliegen: Um das Ganze "clean" zu gestalten, würde ich - wie von dir erwähnt - sowohl für die Berechnung, als auch für die Darstellung eine eigene Variable bzw. Systemvariable verwenden. Vorschlag für die Berechnung: i_count_start und i_count_ende

Für die Umsetzung muss dann an der Stelle, an der auf Urlaub geprüft und, bei vorliegendem Urlaubstag, i_count bzw. jetzt i_count_start auf 0 gesetzt wird, i_count_ende ebenfalls entsprechend gesetzt werden. (Zeilen 247 und 257)

Im Ergebnis würde das dann so aussehen:

i_count_start=-1 und i_count_ende=-1 => wenn kein Urlaub
i_count_start= 0 und i_count_ende= 0 => wenn Urlaub (Einzeltag)
i_count_start= 0 und i_count_ende= i_ende-i_today => wenn Urlaub (Zeitraum)

Umsetzung im Code:

1. Schritt: Zeile 39 (für die neue Systemvariable) ergänzen. Beispiel:

Code: Alles auswählen

string sv_count = "Urlaub-Tage-bis-Beginn,Urlaub-Tage-bis-Ende";
2. Schritt: Im gesamten Skript i_count umbenennen in i_count_start
3. Schritt: Zeile 188 ergänzen mit integer i_count_ende=-1;
4. Schritt: Zeile 247, hinter i_count=0; bzw. jetzt i_count_start=0; ergänzen mit i_count_ende=0;
5. Schritt: Zeile 257, hinter i_count_start=0; ergänzen mit i_count_ende=i_ende-i_today;
6. Schritt: Zeile 293 löschen und ersetzen durch:

Code: Alles auswählen

svObj=svObjects.Get(sv_count.StrValueByIndex(",", 0)); if (svObj){svObj.State(i_count_start);}
svObj=svObjects.Get(sv_count.StrValueByIndex(",", 1)); if (svObj){svObj.State(i_count_ende);}
7. Schritt: 3. letzte Zeile ergänzen (für Debug-Ausgabe) mit:

Code: Alles auswählen

WriteLine("(Debug) Tage bis Urlaubsende: "#i_count_ende.ToString());
Das automatische anlegen der neuen Systemvariablen spare ich mir. Dein dargestellter Code wird so nicht funktionieren. Ich habe das Ganze mal auf die Schnelle eingepflegt und diesem Post angehängt. Er ist von mir noch nicht getestet. Probiere die Änderungen erst einmal selbst umzusetzen, bevor du dir das Skript anschaust.

Viele Grüße
Petrus
.
Urlaubstage_V4.03_complete_KH2.txt
(15.82 KiB) 13-mal heruntergeladen
Zuletzt geändert von Petrus am 11.02.2019, 18:21, insgesamt 1-mal geändert.

Garbsen
Beiträge: 86
Registriert: 12.07.2017, 21:08

Re: Feiertagsberechnung - Skript

Beitrag von Garbsen » 11.02.2019, 13:48

Danke, werde es mal ausprobieren, da es aber noch nicht getestet ist erstmal nur im Script Editor und bedug modus.
Bin zur Zeit unterwegs und habe nur Remote über VPN Zugriff, da bin ich mit Änderungen vorsichtig ;-)
Auf jeden Fall kann ich ja die Variablen schon anlegen.

Wäre schön, wenn Du mir (bei Gelegenheit, eilt nicht) zeigte, was bei meinem Code-Versuch nicht funktionieren würde, damit ich es besser verstehe.

Nochmals danke

K-H
512 Kanäle in 101 Geräten und 145 CUxD-Kanäle in 19 CUxD-Geräten:
--------------------------------------------
http://www.eq-3.de/service/downloads.html
Tips und Tricks für Anfänger: viewtopic.php?t=22801
Programmlogik: viewtopic.php?f=31&t=4251
Webui-Handbuch: https://www.eq-3.de/Downloads/eq3/downl ... h_eQ-3.pdf
Script und Linksammlung: viewtopic.php?f=26&t=27907

Petrus
Beiträge: 101
Registriert: 13.01.2010, 20:53

Re: Feiertagsberechnung - Skript

Beitrag von Petrus » 11.02.2019, 19:29

Habe das Skript jetzt getestet. Die Berechnungen und Anzeige funktioniert wie gewünscht. Einzig beim automatischen anlegen der SV war ein kleiner Bug, den ich behoben habe. Das korrigierte Skript findest du in meinem letzten Post oben.

Zu deinem Code-Versuch. Ich muss gestehen, ich habe nicht ganz bis bis zum Ende gescrollt. Alles in allem war der Ansatz schon i.O. Dennoch möchte ich wie gewünscht darauf eingehen.

Code: Alles auswählen

string sv_count = "Urlaub-Tage-bis,Tage-bis-Urlaubsende";

foreach(s_data1, sv_count.Split(",")) {
    svObj = svObjects.Get(s_data1);
    ! ***Wenn SV vorhanden => ValueTyp pruefen
    if (svObj) {
        if (svObj.ValueSubType() != ivtFloat) { WriteLine(s_data1 # " : ValueSubTyp wrong!"); quit; }
        else { if (b_debug) { WriteLine(s_data1 # " : ValueTyp OK!"); } }
        ! ***andernfalls SV neu anlegen
    } else {
        svObj = dom.CreateObject(OT_VARDP);
        svObjects.Add(svObj.ID());
        svObj.Name(s_data1);
        svObj.ValueType(ivtFloat);
        svObj.ValueSubType(istGeneric);
        svObj.ValueName0("Tage bis zum Urlaub");
        svObj.ValueName1("Tage-bis-Urlaubsende");
        svObj.ValueUnit("");
    	svObj.ValueMin(-1);
    	svObj.ValueMax(1000);
    	svObj.State(-1);
    	svObj.Internal(false);
    	svObj.Visible(true);
    	dom.RTUpdate(false);
        if (b_debug) { WriteLine(s_data1 # " : Systemvariable create!"); }
    }
}
Die Zeilen mit svObj.ValueName0() und svObj.ValueName1() sind für boolsche Systemvariablen und ordnen diesen bei false (ValueName0) und true (ValueName1) einen entsprechenden Klartext zu. Für die Beschreibung der SV wäre hier svObj.DPInfo() korrekt. Werte werden bei einer Zahl (ivtFloat) mit svObj.State() gesetzt. Der Rest sieht soweit gut aus.

Code: Alles auswählen

integer i_idx=0; integer i_data; integer i_today; integer i_count=-1; integer i_count2=-1; string holyday; string s_idx="";
Die Zeile ist korrekt und analog zu meiner Definition entspricht i_count = i_count_start und i_count2 = i_count_ende. Mit den Zuweisungen -1 definierst du zunächst, dass aktuell kein Urlaub vorliegt und damit auch keine Tage bis Urlaubsende existieren. Sollte dies bei der Überprüfung anders sein, werden die Variablen automatisch entsprechend geändert. Also hier alles korrekt und, bis auf die Namensgebung, alles so wie ich es auch im Skript eingefügt habe.

Code: Alles auswählen

if ((i_today >= i_start) && (i_today <= i_ende)) { Urlaub_heute = true; i_count=0; i_count2=i_ende-i_today} ! ...heute Urlaub und...
Bis auf das fehelnde Semikolon hinter i_today hast du auch hier alles richtig gemacht. Genau so ist es auch von mir im Skript eingefügt. Damit hast du die Auswertung bei Zeitraumangaben erledigt. Was jetzt noch fehlt, ist die Auswertung bei der Angabe von einzelnen Urlaubstagen. Denn korrekter Weise müsste ja, wenn z. B. nur heute Urlaub wäre, der Wert für "Tage-bis-Urlaubsende" gleich 0 und nicht wie zu Beginn definiert -1 sein. Also fehlt noch die Anpassung folgender Zeile (an deine Namensgebung angepasst):

Code: Alles auswählen

if (i_today == i_start) { Urlaub_heute = true; i_count=0; i_count2=0;} else { ! ...heute Urlaub, oder...
Damit wären die Berechnungen/Auswertungen erledigt. Für das abschließende setzen der SV's hast du das wie folgt korrekt definiert:

Code: Alles auswählen

svObj=svObjects.Get(sv_count.StrValueByIndex(",", 0)); if (svObj){svObj.State(i_count);}
svObj=svObjects.Get(sv_count.StrValueByIndex(",", 1)); if (svObj){svObj.State(i_count2);}
Der Vollständigkeit wegen muss jetzt nur noch die Zeile für die Debug-Ausgabe ergänzt werden.

Ich würde sagen, im Ansatz alles richtig gemacht. Kompliment und Daumen hoch!

Gruß
Petrus

Garbsen
Beiträge: 86
Registriert: 12.07.2017, 21:08

Re: Feiertagsberechnung - Skript

Beitrag von Garbsen » 11.02.2019, 20:36

Danke, großes Kompliment, bin stolz auf DICH , den ohne dieses Super-Tutorial hätte ich das nie gepackt
512 Kanäle in 101 Geräten und 145 CUxD-Kanäle in 19 CUxD-Geräten:
--------------------------------------------
http://www.eq-3.de/service/downloads.html
Tips und Tricks für Anfänger: viewtopic.php?t=22801
Programmlogik: viewtopic.php?f=31&t=4251
Webui-Handbuch: https://www.eq-3.de/Downloads/eq3/downl ... h_eQ-3.pdf
Script und Linksammlung: viewtopic.php?f=26&t=27907

str1007
Beiträge: 5
Registriert: 06.01.2019, 18:43

Re: Feiertagsberechnung - Skript

Beitrag von str1007 » 14.05.2019, 20:15

Kann es ein, dass lt. Feiertagsliste V2.2 Oster- und Pfingstsonntag nur in Brandenburg Feiertage sind?
Oder habe ich einen Zweig übersehen?
Ist mir Ostern schon aufgefallen, aber man kommt ja zu nix...

Gruß
Stephan

Petrus
Beiträge: 101
Registriert: 13.01.2010, 20:53

Re: Feiertagsberechnung - Skript

Beitrag von Petrus » 14.05.2019, 22:54

Hallo Stephan,

das ist auch so korrekt. Ostersonntag und Pfingstsonntag sind keine gesetzlichen Feiertage. Außer in Brandenburg. Dazu gab es bereits einige Gerichtsprozesse bis zum Bundesarbeitsgericht.

Hier ein Auszug der Klage:

"Die Kläger vertraten die Meinung, Oster- und Pfingstsonntag seien in der christlichen Welt Feiertage. Die Vorinstanzen teilten diese Auffassung und gaben der Klage statt.

Das Bundesarbeitsgericht wies sie nun jedoch zurück. Damit Arbeitnehmer den Feiertagszuschlag halten können, müsse es sich um einen gesetzlichen Feiertag handeln. Dies sei beim Ostersonntag nicht der Fall. Ein Anspruch "aus betrieblicher Übung" scheide ebenfalls aus."


Gruß
Petrus

Antworten

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