FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: Pjg am 13 Oktober 2014, 20:39:33

Titel: Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Pjg am 13 Oktober 2014, 20:39:33
Die von Schulferien.org zur Verfügung gestellten Kalender haben ja die Herausforderung, immer nur pro Jahr definiert zu sein.
Somit muss man sich überlegen, wie man in FHEM jeweils den richtigen Kalender automatisch erwischt.

Aus einem anderen Thread, wo diese Thema bereits gelöst wurde, der aber schon zu ist, stammt dieses Zitat:

Zitatin fhem selbst würde ich mir ein notify anlegen, das auf global:INITIALIZED reagiert und nach dem vollständigen fhem Start diese Funktion aufruft:

Wenn ich mir die Definition in der commandref von INITIALIZED anschaue, und diesen Satz lese, stellt sich mir folgende Frage:

Wie kann das funktionieren, wenn ich FHEM nur alle paar Wochen oder Monate einmal neu starten muss, da es ja rund läuft?
Muss ich nicht besser immer am 1.1. eines jeden Jahres die Funktion aufrufen, und wie könnte ein entsprechender Aufruf aussehen?

Evtl. ein notify auf den Jahreswechsel?
Titel: Antw:Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Baumi am 13 Oktober 2014, 23:25:55
Theoretisch könntest Du doch auch ein at-Kommando nutzen, das einmal pro Tag (z.B. kurz nach Mitternacht) den Ferienkalender des aktuellen Jahres einstellt. Der Befehl würde zwar 364 mal im Jahr umsonst laufen, aber ressourcentechnisch wäre das, glaube ich, kein besonders großes Problem.
Titel: Antw:Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Pjg am 14 Oktober 2014, 12:02:16
Da bin ich mir jetzt nicht so sicher.
Wenn ich einen define schon habe, sagen wir mal am 1.1. erstellt, dann müsste FHEM aber eigentlich meckern, wenn ich den gleichen define am 2.1. schon wieder machen will. Oder etwa nicht?

Wie's ausschaut, funktioniert die Lösung von betateilchen nur auf den ersten Blick:
Da ja mit restart noch keine Defiition vorhanden ist, sondern diese ja erst quasi beim hochfahren von FHEM erstellt wird. Somit muss zuvor auch nichts gelöscht werden.
Problem ist jedoch, das dies nur funktioniert, wenn am 1.1. um kurz nach 0:00 auch wirklich ein Restart durchgeführt wird.
Wenn dieser restart erst am 2.2. erfolgt, sind die Weihnachtsferien schon vorbei :-)

Ein zusätzlicher defineFerien(2015) am 1.1. funktioniert jedoch nicht, da schon ein Kalender für 2014 vorhanden ist. Die Defintion wird in diesem Fall nicht geändert, aber auch nicht weiter kommentiert.

Ich wewrde es einmal bei Gelegenheit mit CommandModify probieren.
Also anstatt so:
Zitatsub defineFerien($) {
  my ($year) = @_;
  my $url = "http://www.schulferien.org/iCal/Ferien/icals/Ferien_Bayern_$year.ics";
  CommandDefine(undef, "Bayern_Ferien Calendar ical url $url 21600");
  return;
}

so:
sub defineFerien($) {
  my ($year) = @_;
  my $url = "http://www.schulferien.org/iCal/Ferien/icals/Ferien_Bayern_$year.ics";
  CommandModify(undef, "Bayern_Ferien Calendar ical url $url 21600");
  return;
}

Ich hoffe, das er dann die bestehende Definition ändert, und somit über einen täglichen Aufruf aktualisiert werden kann.
Mal sehen.
Titel: Antw:Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Pjg am 14 Oktober 2014, 14:43:57
Die Hoffnung stirbt zuletzt. Also gerade eben...
Leider ändert ein CommandModify ebenfalls nicht eine bestehende Definition.

Ich gebe auf und habe zwei Kalender definiert.
Jeweils für's aktuelle und Folgejahr. Ich muss nun immer manuell eingreifen und das Jahr abändern.

Schade, aber ich komme mit meinen Mitteln nicht weiter.
Titel: Antw:Aufgegeben: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Baumi am 14 Oktober 2014, 16:28:36
Mit CommandDefine() und Co habe ich noch nie gearbeitet, aber die folgende Konstruktion funktioniert bei mir ganz gut, um FHEM-Dummys oder -Funktionen ggf. neu zu definieren:

{
fhem("delete auto_weather_repeat") if (Value("auto_weather_repeat") ne "");;
fhem("define auto_weather_repeat at +00:10:00 {alertWeather(1)}");;
}


Ließe sich das evtl. so anpassen, dass es bei Dir klappt?
Titel: Antw:Aufgegeben: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Pjg am 14 Oktober 2014, 17:22:58
Baumi, Du bist mein Held :-)

So funktioniert es:

Zitatsub defineFerien($) {
  my ($year) = @_;
  my $url = "http://www.schulferien.org/iCal/Ferien/icals/Ferien_Bayern_$year.ics";
  fhem("delete Bayern_Ferien");
  CommandDefine(undef, "Bayern_Ferien Calendar ical url $url 21600");
  return;
}

Auf der Basis kann man nun auch ein doif aufbauen, welches bei (jedem neustart) oder (um 0:05 Uhr am 1. eines jeden monats (hauptsächlich natürlich am 1.1.)) diese defineFerien aufruft.
Oder eben ein at für den 1. eines Monats, und ein notify wie bei betateilchen für den neustart.

Danke.
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Puschel74 am 14 Oktober 2014, 17:36:49
Hallo,

wenn die Frage gelöst ist dann bitte dem Betreff noch ein Gelöst vorne dran.
Danke.


Grüße

Edith: Ich muss mal meinen Bildschirm putzen  ::)
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Spartacus am 15 Oktober 2014, 13:01:11
Hi Pjg,
kannst Du die komplette Lösung mal posten?

Danke,
Spartacus.
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Pjg am 15 Oktober 2014, 20:43:43
fhem.cfg

Zitat# Schulferien
define Ferientag dummy
define makeFerien notify global:INITIALIZED {defineFerien($year)}
define makeFerien2 at *00:05 { if ( $mday == 1) {defineFerien($year)}}
define Job_Ferien_Check notify Ferien { fhem "set Ferientag " . (ReadingsVal("Ferien", "modeStart", "") =~ "schulferien" ? 1: 0) }

myutils
Zitatsub defineFerien($) {
  my ($year) = @_;
  my $url = "http://www.schulferien.org/iCal/Ferien/icals/Ferien_Rheinland_Pfalz_$year.ics";
  fhem("delete Ferien");
  CommandDefine(undef, "Ferien Calendar ical url $url 86400");
  return;
}

Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Spartacus am 15 Oktober 2014, 21:54:05
Halo,
Danke für Deinen Post. Du fragst mit mday=1 den ersten Tag eines Monats ab. Müsste man hier nicht auch den Monat mon=0 für Januar abfragen? Sonst läuft Dein at doch jeden 1. eines Monats um 5 nach 12.

Oder was übersehe ich gerade....
Spartacus
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Pjg am 15 Oktober 2014, 22:03:41
Siehst Du fast richtig. $month ==1 könnte man noch rein nehmen.
Hab ich jetzt aber mal gelassen. Wird dann halt 11 mal zuviel aufgerufen.
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Deen am 04 Januar 2016, 13:09:17
Frohes neues Jahr an alle!
Für die Steuerung meine Rollladen habe ich die Lösung von Pjg Angewendet, das hat Funktioniert bis Jahreswechselt jetzt wird nach neues Jahr kein Feiertag erkannt.
Weiß es jemand mehr drüber?
Vielen Dank.
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Spartacus am 04 Januar 2016, 13:49:46
Hallo zusammen
das Problem von Deen habe ich auch. Der Code von oben hat einen Haken:

Wenn die Ferien um 00:05:00 Uhr an Neujahr auf das neue Kalenderjahr aktualisiert werden, dann sind die aktuellen Weihnachtsferien futsch, denn diese sind im Kalender für 2015 angegeben (22.12.2015-07.01.2016).

Hat dafür jemand eine Lösung?
Spartacus
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Baumi am 05 Januar 2016, 00:25:09
Es müsste mit Hilfe der internen FHEM-Variablen für Tag und Monat gehen. (Nicht getestet!)

sub defineFerien($) {
  my ($year) = @_;
  my $url = "http://www.schulferien.org/iCal/Ferien/icals/Ferien_Rheinland_Pfalz_$year.ics";
  if ($month > 1 || $mday > 15) {
    fhem("delete Ferien");
    CommandDefine(undef, "Ferien Calendar ical url $url 86400");
  }
  return;
}


(Die Kombination aus delete und CommandDefine ließe sich inzwischen auch durch ein defmod ersetzen.)

Mit dieser Routine wird (wenn ich mich nicht vertippt habe) der Kalender zwischen dem 1. und 15. Januar nicht aktualisiert. Und ich glaube, am 15.01. sind nirgendwo mehr Ferien.

Alternativ könnte man die Abfrage auch auf einen einzelnen Zeitraum beschränken (z.B. ändere das Define nur am soundsovielten Januar), aber das birgt die Gefahr, dass ausgerechnet in der Minute, in der die Funktion aufgerufen werden müsste, aus irgendwelchen Gründen gerade fhem nicht läuft und man das ganze Jahr über den falschen Kalender hat. Ein einzelnes define pro Tag kostet nicht viel Rechenzeit und beugt diesem Problem vor.
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Spartacus am 05 Januar 2016, 12:25:00
Hallo Baumi,
das ist es noch nicht ganz, denn durch:
define makeFerien notify global:INITIALIZED {defineFerien($year)}
werden die Ferien bei jedem Booten mit dem aktuellen Jahr angelegt. Das muss man noch irgendwie abfangen...
Christian

NACHTRAG:
das if ($month > 1 || $mday > 15) {
    fhem("delete Ferien");

funktioniert noch nicht! Der Befehl wird ausgeführt.
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Baumi am 05 Januar 2016, 13:25:55
Sorry, das kommt davon, wenn man mitten in der Nacht ungetesteten Code postet. :)

So funktioniert's bei mir:

sub defineFerien($$$) {
  my ($year, $month, $mday) = @_;
  my $url = "http://www.schulferien.org/iCal/Ferien/icals/Ferien_Rheinland_Pfalz_$year.ics";
  if ($month > 1 || $mday > 15) {
    fhem("delete Ferien");
    CommandDefine(undef, "Ferien Calendar ical url $url 86400");
  }
  return;
}


Achtung: Alle defines und anderen Strukturen, die diese Funktion aufrufen, müssen dann auch geändert werden. Der Aufruf muss jeweils so aussehen:

defineFerien($year,$month,$mday);;

Dass der Befehl bei jedem Boot ausgeführt wird, sollte m. E. keinen Unterschied machen. Das Datum wird ja übergeben und während der Ausführung abgefragt, d.h. wenn das Booten Anfang Januar stattfindet, wird dabei auch nix geändert. Oder liefert FHEM während des Startvorgangs fehlerhafte Werte für $year, $month und $mday?
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Spartacus am 05 Januar 2016, 13:29:32
Hallo,
ich glaube ich habe es jetzt:
Der Knackpunkt ist, dass $month und $mday übergeben werden müssen. Sonst kann die Routine das nicht auswerten. Vielleicht hat jemand eine bessere Lösung. Aber so scheint es zu funzen.


# Neujahr um 00:01 Uhr
#
define cal.04.Schulferien.not at *00:01:00 \
set cal.01.Schulferien reload;;  \
{ \
if ( $mday == 1 && $month == 1)\
{ \
  defineFerien($year,$month,$mday)\
}\
}


und dann
define cal.03.Schulferien.not notify global:INITIALIZED {defineFerien($year,$month,$mday)}

und in myutils...
sub defineFerien($$$)
{
  my ($year,$month,$mday) = @_;
  my $url = "http://www.schulferien.org/iCal/Ferien/icals/Ferien_Nordrhein_Westfalen_$year.ics";
  if ($month > 1 || $mday > 15)
  {
   fhem("delete cal.01.Schulferien");
   CommandDefine(undef, "cal.01.Schulferien Calendar ical url $url 100000");
  }
  return;
}


Spartacus
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Spartacus am 05 Januar 2016, 13:30:42
 8)
da warst Du eine paar Sekunden schneller!
Christian
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Baumi am 05 Januar 2016, 13:56:01
 8)

Du kannst Dir die Parameter-Übergabe natürlich auch komplett sparen, wenn Du statt dessen innerhalb der Funktion das aktuelle Datum ausliest. Allerdings musst Du die Ausgabewerte von localtime noch ein bisschen aufbereiten, um sie zu verwenden. (1900 zum Jahr addieren, und 1 zum Monat.


sub defineFerien()
{
  my($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
  $year += 1900;
  $month ++;
  my $url = "http://www.schulferien.org/iCal/Ferien/icals/Ferien_Nordrhein_Westfalen_$year.ics";
  if ($month > 1 || $mday > 15)
  {


usw.

Dann müssten die Aufrufe in ein einfaches defineFerien();; geändert werden.
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Spartacus am 05 Januar 2016, 15:53:34
Hi Baumi,
habe jetzt Deine letzte Variante genommen. Die ist viel eleganter....

Danke Dir für Deine Hilfe..
Christian
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Deen am 06 Januar 2016, 20:17:07
Super! Vielen Dank!
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Deen am 06 Januar 2016, 21:05:01
Ich bin ein Anfänger, verstehe das richtig? Ich habe so in ".cfg angegeben:

# Neujahr um 00:01 Uhr
#
define cal.04.Schulferien.not at *20:41:00 \
set cal.01.Schulferien reload;;  \
{ \
if ( $mday == 1 && $month == 1)\
{ \
  defineFerien($year,$month,$mday)\
}\
}

define cal.03.Schulferien.not notify global:INITIALIZED {defineFerien($year,$month,$mday)}


# Schulferien
define Ferientag dummy
define makeFerien notify global:INITIALIZED {defineFerien($year)}
define makeFerien2 at *20:30:00 { if ( $mday == 1) {defineFerien($year)}}
define Job_Ferien_Check notify Ferien { fhem "set Ferientag " . (ReadingsVal("Ferien", "modeStart", "") =~ "schulferien" ? 1: 0) }

define K.Zimmer1 at *06:10:00 { if ( !($we) && !(Value("Ferientag")) ) { fhem("set harmony_24908328 command directionup");; } }
define K.Zimmer2 at *06:10:20 { if ( !($we) && !(Value("Ferientag")) ) { fhem("set harmony_24908328 command stop");; } }
define K.Zimmer3 at *10:00:00 { if (($we) || (Value("Ferientag"))) {fhem("set harmony_24908328 command directionup");; } }
define K.Zimmer4 at *10:00:20 { if (($we) || (Value("Ferientag"))) {fhem("set harmony_24908328 command stop");; } }



und dann in myutils:

package main;
use strict;
use warnings;
use POSIX;
sub
myUtils_Initialize($$)
{
my ($hash) = @_;
}

sub defineFerien()
{
  my($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
  $year += 1900;
  $month ++;
  my $url ="http://www.schulferien.org/iCal/Ferien/icals/Ferien_Baden_Wuerttemberg_$year.ics";
  if ($month > 1 || $mday > 15)
  {
fhem("delete cal.01.Schulferien");
   CommandDefine(undef, "cal.01.Schulferien Calendar ical url $url 100000");
  }
  return;
}
1;

ist so korrekt?
Vielen Dank
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Spartacus am 06 Januar 2016, 21:48:02
Hi,
im Prinzip richtig.

Du brauchst zwei Trigger für das Aktualisieren der Kalender: Einmal beim Booten und einmal an Neujahr bzw. nach den Weihnachtsferien durch ein Notify. Bei mir läuft das am 11.01. Die Abfrage auf das Datum in in der myFerien.pm verhindert, dass die neue Kalenderdatei beim booten nicht vor Ende der aktuellen Weihnachtsferien angelegt wird. Sonst gehen die Ferientage im Januar verloren. In der Regel sind die Ferien in den meisten Bundesländern spätestens am 10.01. beendet. Deshalb erstelle ich den neuen Kalender am 11.01.

Hier mein Code, den ich aus der fhem.cfg kopiert habe. Die Namen der Kalender kannst Du natürlich ändern..

booten:
define cal.03.Schulferien.not notify global:INITIALIZED {defineFerien()}

nach den Weihnachtsferien (hier 11.01.):
define cal.04.Schulferien.not at *00:01:00 \
set cal.01.Schulferien reload;;  \
{ \
if ( $mday == 11 && $month == 1)\
{ \
  defineFerien()\
}\
}


aus der 99_myFerien.pm

package main;
use strict;
use warnings;
use POSIX;
use Time::Local;
sub myFerien_Initialize($$)
{
my ($hash) = @_;
}

sub defineFerien()
{
  my($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
  $year += 1900;
  $month ++;
  my $url = "http://www.schulferien.org/iCal/Ferien/icals/Ferien_Nordrhein_Westfalen_$year.ics";
  if ($month > 1 || $mday > 10)
  {
   fhem("delete cal.01.Schulferien");
   CommandDefine(undef, "cal.01.Schulferien Calendar ical url $url 100000");
  }
  fhem("set cal.01.Schulferien reload");
  fhem("attr cal.01.Schulferien room 99-Dienste");
  fhem("attr cal.01.Schulferien alias Ferien NRW");
  fhem("attr cal.01.Schulferien group Online Kalender");
  return;
}
1;

Ich hoffe, das hilft jetzt!
Spartacus
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Baumi am 07 Januar 2016, 09:09:33
Fehlt beim Notify für den 11.01. nicht noch ein Semikolon (oder zwei) hinter "defineFerien()"?
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Deen am 07 Januar 2016, 16:20:09
Vielen Dank.
D. h. dass von 01.01 bis 10.1 keine Feiertagen erkannt werden oder?
mfg
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Spartacus am 07 Januar 2016, 17:02:27
Hallo,
das heißt, dass vom 01.01. bis 10.01. der alte Kalender (also 2015) gültig ist und der 2016er erst am 11.01. geladen wird. Die Weihnachtsferien (z.B.: 22.12.2015-06.01.2016) stehen immer im 2015er Kalender. Und wenn Du in der Neujahrsnacht den 2016er Kalender lädst, dann sind die Ferientage im Januar 2016 futsch!

Deshalb wird der 2016er Kalender erst geladen, wenn die Weihnachtsferien beendet sind.
Christian
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Deen am 07 Januar 2016, 18:32:37
Danke Christian.
Titel: Antw:Gelöst: Aktualisierung Kalenderjahr bei Schulferien
Beitrag von: Rince am 10 Januar 2016, 16:30:04
Sorry für das späte aufspringen auf diesen mittlerweile gelösten Fall.

pah hatte für diese Thematik mal seine eigenen Skripte zur Verfügung gestellt, die selbiges (und noch etwas mehr) ganz vorzüglich lösen:

Ist hier zum nachlesen:
http://forum.fhem.de/index.php/topic,36244.msg299631.html#msg299631 (http://forum.fhem.de/index.php/topic,36244.msg299631.html#msg299631)