Gelöst: Aktualisierung Kalenderjahr bei Schulferien

Begonnen von Pjg, 13 Oktober 2014, 20:39:33

Vorheriges Thema - Nächstes Thema

Baumi

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?

Spartacus

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
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R

Spartacus

 8)
da warst Du eine paar Sekunden schneller!
Christian
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R

Baumi

 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.

Spartacus

Hi Baumi,
habe jetzt Deine letzte Variante genommen. Die ist viel eleganter....

Danke Dir für Deine Hilfe..
Christian
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R


Deen

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

Spartacus

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
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R

Baumi

Fehlt beim Notify für den 11.01. nicht noch ein Semikolon (oder zwei) hinter "defineFerien()"?

Deen

Vielen Dank.
D. h. dass von 01.01 bis 10.1 keine Feiertagen erkannt werden oder?
mfg

Spartacus

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
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R


Rince

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
Wer zu meinen Posts eine Frage schreibt und auf eine Antwort wartet, ist hiermit herzlich eingeladen mich per PN darauf aufmerksam zu machen. (Bitte mit Link zum betreffenden Thread)