95_holiday.pm - Erweiterung um eigene Berechnungen

Begonnen von betateilchen, 15 November 2018, 22:37:56

Vorheriges Thema - Nächstes Thema

betateilchen

Ich weiß noch nicht, wie man das am besten dokumentieren könnte, damit es verstanden wird, aber ich will hier einfach mal meine heutigen Basteleien festhalten.


Index: 95_holiday.pm
===================================================================
--- 95_holiday.pm       (revision 17751)
+++ 95_holiday.pm       (working copy)
@@ -199,6 +199,19 @@
         Log 1, "Wrong distance spec: $l";
         next;
       }
+    } elsif($l =~ m/^6/) { # own calculation
+        my @args = split(" +", $l, 4);
+        my $res = "?";
+        no strict "refs";
+        eval { $res = &{$args[1]}($args[2]); };
+        use strict "refs";
+        if($@) {
+           Log 1, "holiday: Error in own function: $@";
+           next;
+        }
+        if($res eq $fordate) {
+           $found = $args[3];
+        }
     }
     push @foundList, $found if($found);



in der 99_myUtils.pm steht


sub calcAdvent {
  my ($aNum) = shift;
  $aNum //= 21; # 1. Advent als default berechnen
  my $jahr = (localtime(time))[5]+1900;
  my $time = str2time("$jahr-12-25");
  my $wday = (localtime($time))[6];
  $wday = $wday ? $wday : 7;
  $time -= ($wday+$aNum)*86400;
  my $m = (localtime($time))[4]+1;
  my $d = (localtime($time))[3];
  return sprintf("%02d-%02d",$m,$d);
}


in der .holiday Datei steht


6 calcAdvent 21 1.Advent
6 calcAdvent 14 2.Advent
6 calcAdvent  7 3.Advent
6 calcAdvent  0 4.Advent


Erklärung:

6 = neuer Typ in der Datei
calcAdvent = Name einer Funktion, die aufgerufen werden soll, um ein Datum zu berechnen
21 / 14 / 7 / 0 = Parameter, die an die Funktion übergeben werden
1./2./3./4. Advent = Feiertagstext, der im reading auftaucht

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

Wenn Du auch noch fuer die Dokus einen Abschnitt hinzufuegst, dann checke ich das ein :)

betateilchen

Am Wochenende will ich Lebkuchen und Weihnachtsplätzchen backen, mal schauen ob ich auch noch zum Dokuschreiben komme :)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

was man heute kann besorgen, das verschiebe nicht... (ach, das erzähle ich dann morgen zu Ende)


Index: 95_holiday.pm
===================================================================
--- 95_holiday.pm       (revision 17751)
+++ 95_holiday.pm       (working copy)
@@ -199,6 +199,19 @@
         Log 1, "Wrong distance spec: $l";
         next;
       }
+    } elsif($l =~ m/^6/) { # own calculation
+        my @args = split(" +", $l, 4);
+        my $res = "?";
+        no strict "refs";
+        eval { $res = &{$args[1]}($args[2]); };
+        use strict "refs";
+        if($@) {
+           Log 1, "holiday: Error in own function: $@";
+           next;
+        }
+        if($res eq $fordate) {
+           $found = $args[3];
+        }
     }
     push @foundList, $found if($found);

@@ -430,6 +443,28 @@
             5 1 Mon 01 31 First Monday after Jan, 31st (1st Monday in February)<br>
           </ul>
           </li>
+      <li>6<br>
+          Use a perl function to calculate a date. Function must return the result as
+          an exact date in format "mm-dd", e.g. "12-02" <br/>
+          <br/>
+          Example:<br>
+          <ul><code>
+            6 calcAdvent 21 1.Advent<br>
+            6 calcAdvent 14 2.Advent<br>
+            6 calcAdvent  7 3.Advent<br>
+            6 calcAdvent  0 4.Advent<br>
+          </code></ul>
+          <br/>
+          Explanation:<br/>
+          <ul><code>
+          calcAdvent = name of function, e.g. included in 99_myUtils.pm<br/>
+          21 = parameter given to function<br/>
+          1.Advent = text to be shown in readings<br/>
+          </code></ul>
+          <br/>
+          this will call "calcAdvent(21)" to calculate a date.<br/>
+          Errors will be logged in Loglevel 1.<br/>
+      </li>
     </ul>
   </ul>
   <br>
@@ -560,6 +595,28 @@
             5 1 Mon 01 31 Erster Montag in Februar<br>
           </ul>
           </li>
+      <li>6<br>
+          Datum mit einer perl Funktion berechnen. Das Ergebnis muss ein exaktes
+          Datum im Format "mm-dd" sein, z.B."12-02" <br/>
+          <br/>
+          Beispiel:<br>
+          <ul><code>
+            6 calcAdvent 21 1.Advent<br>
+            6 calcAdvent 14 2.Advent<br>
+            6 calcAdvent  7 3.Advent<br>
+            6 calcAdvent  0 4.Advent<br>
+          </code></ul>
+          <br/>
+          Erkl&auml;rung:<br/>
+          <ul><code>
+          calcAdvent = Name der Funktion, z.B. enthalten in 99_myUtils.pm<br/>
+          21 = Parameter zum Funktionsaufruf<br/>
+          1.Advent = Text f&uuml;r die Anzeige in readings<br/>
+          </code></ul>
+          <br/>
+          erzeugt einen Funktionsaufruf "calcAdvent(21)" zur Berechnung eines Datums.<br/>
+          Fehler werden im Loglevel 1 protokolliert.<br/>
+      </li>
     </ul>
   </ul>
   <br>
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig


betateilchen

Das ging ja erstaunlich widerspruchsfrei :) Danke!
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Christoph Morrison

Ich würde dann folgendes beisteuern:

de_christmas.holiday


6   calcAdvent 21   1.Advent
6   calcAdvent 14   2.Advent
6   calcAdvent  7   3.Advent
6   calcAdvent  0   4.Advent
1   12-24           Heiliger Abend
1   12-25           1. Weihnachtstag
1   12-26           2. Weihnachtstag


Recht so?

betateilchen

Nein, lass das bitte. Einträge vom Typ = 6 müssen vom Anwender selbst in seine lokale .holiday Datei eingefügt werden, wenn er sie für irgendwas benötigt.

Die Funktion calcAdvent() ist nur ein Beispiel. Die verwendete Funktion muss in der jeweiligen FHEM Installation vom Anwender manuell bereitgestellt werden, es ist keine Funktionalität des holiday Moduls selbst.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Christoph Morrison

Zitat von: betateilchen am 16 November 2018, 15:35:12
Nein, lass das bitte. Einträge vom Typ = 6 müssen vom Anwender selbst in seine lokale .holiday Datei eingefügt werden, wenn er sie für irgendwas benötigt.

Das finde ich ziemlich ungeschickt, auch wenn du es in die Doku aufnimmst, bzw. genau deswegen. Die Doku liest sich jetzt nämlich tatsächlich so, als würde calcAdvent() nun in 99_myUtils zu finden sein (und ja ich weiß für was e.g./z.B. steht, die myUtils gut ist und dass sie nicht aus dem Repository aktualisiert wird).

Ich fände es besser, wenn entweder die Daten einfach fest in der/einer holiday-Datei stehen (ich mache das auch gerne regelmäßig neu) oder aber dass die Beispielfunktion aus der Doku, egal wie sie heißt, dann auch regulär verfügbar ist oder aber die Doku noch mal klarstellt, dass die konkrete Beispielfunktion calcAdvent() vom User selbst angelegt werden muss. Die Funktion ist nun in der Doku ein loose end, da sie auch nicht dokumentiert ist.

betateilchen

Ich hätte die Funktion im Beispiel auch "Heinz" nennen können. Würden wir dann auch diskutieren?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Zitat von: Christoph Morrison am 16 November 2018, 16:03:15
Ich fände es besser, wenn entweder die Daten einfach fest in der/einer holiday-Datei stehen (ich mache das auch gerne regelmäßig neu)

Es geht doch hier überhaupt nicht darum, die Adventsdaten in den holiday Dateien zu haben.

Es geht darum, dass man nun mittels eigener Funktionen variable Feiertage/Ereignisse in den holiday devices berücksichtigen kann. Du kannst damit auch die Müllabfuhrtermine in einem holiday device anzeigen lassen, wenn Du die entsprechende Funktion baust und verwendest.

Es macht überhaupt keinen Sinn, solche variablen Daten in den holiday Dateien regelmäßig (jährlich) zu aktualisieren. Denn wenn ein Benutzer die .holiday Datei als "privateCopy" verwendet, bekommt er von den per update gelieferten .holiday Dateien überhaupt nichts mehr mit.

Mach Dich bitte mit der Funktionsweise des holiday Moduls vertraut, bevor Du jetzt mit gutgemeinten, aber wirkungslosen Änderungen an den holiday Dateien vermeidbare Verwirrung stiftest.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Toto1973

Ich blicke noch nicht ganz durch, wie das jetzt berechnet wird.
Aber könnte man damit auch den Totensonntag, der ja eine Woche vor dem 1. Advent liegt und den Volkstrauertag, der 2 Wochen vor dem 1. Advent liegt, berechnen?
Raspberry PI2, Rademacher DuoFern Stick, CUL, 2 x SCC,  JeeLink 868 Mhz, JeeLink 433 Mhz, 3x Magic UFO LED WiFi Controller, 4x MAX BC-RT-TRX-CyG, 2x MAX Fensterkontakt, 5x Rademacher Gurtwickler, 6x TX29DTH-it, 2x TX25-it als Helligkeitssensor, 1X HM-ES-PM, 6x Sonoff, 7x G-Homa, PIR-1000

rudolfkoenig

Ja, man kann damit alles berechnen, weil perl eine Turing-Vollstaendige Sprache ist.
Den Algorithmus dafuer mitzuliefern war nicht Absicht des Autors, und der Beispiel offensichtlich ungluecklich gewaehlt :)

Wer Advent / Adventszeit anzeigen will, der kann es auch einfacher:5 -4 Sun 12 25 1. Advent
5 -4 Sun 12 25 Adventszeit
5 -3 Mon 12 25 Adventszeit
5 -3 Tue 12 25 Adventszeit
5 -3 Wed 12 25 Adventszeit
5 -3 Thu 12 25 Adventszeit
5 -3 Fri 12 25 Adventszeit
5 -3 Sat 12 25 Adventszeit
5 -3 Sun 12 25 2. Advent
5 -3 Sun 12 25 Adventszeit
5 -2 Mon 12 25 Adventszeit
5 -2 Tue 12 25 Adventszeit
5 -2 Wed 12 25 Adventszeit
5 -2 Thu 12 25 Adventszeit
5 -2 Fri 12 25 Adventszeit
5 -2 Sat 12 25 Adventszeit
5 -2 Sun 12 25 3. Advent
5 -2 Sun 12 25 Adventszeit
5 -1 Mon 12 25 Adventszeit
5 -1 Tue 12 25 Adventszeit
5 -1 Wed 12 25 Adventszeit
5 -1 Thu 12 25 Adventszeit
5 -1 Fri 12 25 Adventszeit
5 -1 Sat 12 25 Adventszeit
5 -1 Sun 12 25 4. Advent
5 -1 Sun 12 25 Adventszeit
1 12-19 Adventszeit
1 12-20 Adventszeit
1 12-21 Adventszeit
1 12-22 Adventszeit
1 12-23 Adventszeit
1 12-24 Adventszeit



Das liefert dann sowas wie:
Zitat2019-12-16 09:30:16   state           Adventszeit
     2019-12-16 09:30:16   tomorrow        Adventszeit
     2019-12-16 09:30:16   yesterday       3. Advent, Adventszeit

betateilchen

#13
Zitat von: rudolfkoenig am 16 Dezember 2019, 09:32:27
Den Algorithmus dafuer mitzuliefern war nicht Absicht des Autors, und der Beispiel offensichtlich ungluecklich gewaehlt


  • der Algorithmus steht im ersten Beitrag dieses Threads
  • das Beispiel "Advent" war damals bei mir der Anlass, weshalb ich diese Erweiterung vorgeschlagen hatte

Zitat von: rudolfkoenig am 16 Dezember 2019, 09:32:27
Wer Advent / Adventszeit anzeigen will, der kann es auch einfacher:

Auch eine gute Idee. Zumindest die Einträge vom Typ 1 müssen dann aber jedes Jahr einmal manuell gepflegt werden.




Zitat von: Toto1973 am 15 Dezember 2019, 23:18:56
Aber könnte man damit auch den Totensonntag, der ja eine Woche vor dem 1. Advent liegt und den Volkstrauertag, der 2 Wochen vor dem 1. Advent liegt, berechnen?

Um beim unglücklich gewählten Beispiel zu bleiben - ja.


6 calcAdvent 35 Volkstrauertag
6 calcAdvent 28 Totensonntag
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Toto1973

Vielen Dank für die Antwort!

Das erspart mir das Angleichen der Kalenderdatei. Von daher finde ich das Beispiel gut gewählt :-)

P.S.: Ich nutze es, um meine Adventsbeleuchtung zu steuern. Ist diese vor dem Totensonntag schon installiert, wird sie am Totensonntag ausgeschaltet und am Tag danach wieder an.
Raspberry PI2, Rademacher DuoFern Stick, CUL, 2 x SCC,  JeeLink 868 Mhz, JeeLink 433 Mhz, 3x Magic UFO LED WiFi Controller, 4x MAX BC-RT-TRX-CyG, 2x MAX Fensterkontakt, 5x Rademacher Gurtwickler, 6x TX29DTH-it, 2x TX25-it als Helligkeitssensor, 1X HM-ES-PM, 6x Sonoff, 7x G-Homa, PIR-1000