automatisiertes Definieren und Einbinden von Feiertagen/Schulferien als ical

Begonnen von Ralli, 13 April 2015, 15:32:55

Vorheriges Thema - Nächstes Thema

Ralli

Hallo zusammen,

um zukünftige iCals von Feiertagen oder/und Ferien einzubinden (vorausgesetzt, sie sind an der entsprechenden URL zu finden), habe ich mir folgende at-Definitionen gebastelt:


define Neuer_Ferien_Kalender_Check at *10:00 {if ((strftime "%d-%m",localtime) eq "30-12"){fhem ("define Ferien".((strftime "%Y",localtime)+1)." Calendar ical url http://www.schulferien.org/iCal/Ferien/icals/Ferien_Rheinland_Pfalz_".((strftime "%Y",localtime)+1).".ics");; fhem("save")}}



define Neuer_Feiertags_Kalender_Check at *10:00 {if ((strftime "%d-%m",localtime) eq "30-12"){fhem ("define Feiertage".((strftime "%Y",localtime)+1)." Calendar ical url http://www.schulferien.org/iCal/Feiertage/icals/Feiertage_Rheinland_Pfalz_".((strftime "%Y",localtime)+1).".ics");; fhem("save")}}


Damit wird erreicht, dass jeden Tag um 10 Uhr geprüft wird, ob wir den 30.12. haben (at oder DOIF unterstützen bis jetzt keine Datums-Definitionen). Ist dies der Fall, wird ein neues Calendar-Device mit Namen Ferien20xy bzw. Feiertage20xy angelegt - allerdings ohne entsprechende Prüfung, wir gehen einfach aus, dass der Link bzw. das iCal-File existiert!

Die Auswertung bezüglich eines tatsächlichen Ferien- oder Feiertages läuft dann angelehnt an Wiki wie folgt:


define Feiertag dummy
define Feiertag_Check notify Feiertage[0-9]*:modeStart.* {ReadingsVal("Feiertage".(strftime "%Y",localtime), "modeStart", "") =~ "schulferien"? fhem("set Feiertag 1"): fhem("set Feiertag 0")}



define Ferientag dummy
define Ferientag_Check notify Ferien[0-9]*:modeStart.* {ReadingsVal("Ferien".(strftime "%Y",localtime), "modeStart", "") =~ "schulferien"? fhem("set Ferientag 1"): fhem("set Ferientag 0")}
Gruß,
Ralli

Proxmox 8.1 Cluster mit HP ED800G2i7, Intel NUC11TNHi7+NUC7i5BNH, virtualisiertes fhem 6.3 dev, virtualisierte RaspberryMatic (3.75.6.20240316) mit HB-RF-ETH 1.3.0 / RPI-RF-MOD, HM-LAN-GW (1.1.5) und HMW-GW, FRITZBOX 7490 (07.57), FBDECT, Siri und Alexa

FHEMAN

Hi Ralli,

danke, dass du den Code hier veröffentlichst!
Für die Faulen: das aktuelle Jahr wird erstellt mit
{fhem ("define Feiertage".((strftime "%Y",localtime))." Calendar ical url http://www.schulferien.org/iCal/Feiertage/icals/Feiertage_Sachsen_Anhalt_".((strftime "%Y",localtime)).".ics")}

in der Kommandozeile oben + SAVE nicht vergessen.
Übrigens sind schon jetzt die Feiertag ics Dateien für die nächsten hundert Jahre verfügbar :)
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

Prof. Dr. Peter Henning

#2
Hm, dieses Codebeispiel hat den Nachteil, dass in jedem Jahr ein neues Calendar-Device aufgemacht wird. Das bedeutet, dass alle weiteren Routinen umgeschrieben werden müssen.

Also besser: Am 30.12. das alte löschen. Dann neu anlegen mit den Daten vom kommenden Jahr.

Auch erschließt sich mir nicht der Sinn eines getrennten Dummy für Feiertage und Ferientage, die jeweils nur einen booleschen Wert haben. M.E: besser, eine Funktion "getDayStatus()" einzuführen, die Werte "Feiertag", "Ferientag" etc. liefern kann und ggf. auch als Argument ein beliebiges Datum bekommt.

Zweite Schwäche: so wird jede Stunde der gesamte Kram geholt...

LG

pah

Ralli

Nein, es muss keine Routine umgeschrieben werden, da der von mir verwendete Notify auf Events in den Readings modeStart aller dem Suchmuster entsprechenden Kalender reagiert, dabei das aktuelle Jahr allerdings für die Readingsabfrage verwendet, um dann entweder Ferientag oder Feiertag zu setzen.

Der zweite "Nachteil" ist auch nicht vorhanden, da Du im jeweiligen Calendar-Device das Poll-Intervall variieren kannst.
Gruß,
Ralli

Proxmox 8.1 Cluster mit HP ED800G2i7, Intel NUC11TNHi7+NUC7i5BNH, virtualisiertes fhem 6.3 dev, virtualisierte RaspberryMatic (3.75.6.20240316) mit HB-RF-ETH 1.3.0 / RPI-RF-MOD, HM-LAN-GW (1.1.5) und HMW-GW, FRITZBOX 7490 (07.57), FBDECT, Siri und Alexa

Prof. Dr. Peter Henning

Ich habe mich doch eigentlich klar ausgedrückt: Erstens geht es nicht um den kleinen notify oben - sondern in einer komplexen FHEM-Installation greifen sicher mehr Routinen auf den Kalender zu.

Zweitens ist es unprofessionell, Mengen von alten Daten (etwa die Feiertage des abgelaufenen Jahres...) vorzuhalten (sogar in der Konfigurationsdatei steht davon noch etwas). _Wenn_ man das schon unbedingt in einem FHEM-Skript statt in einer ordentlichen und viel besser wartbaren Perl-Subroutine abhandeln will, sollte deshalb das andere Device mindestens deaktiviert, besser komplett gelöscht werden.

Drittens habe ich keinerlei Verständnis für das automatische Anlegen von Devices, wenn diese hinterher noch manuell bearbeitet werden müssen, um ihre Abfragefrequenz zu reduzieren.

Damit ich nicht nur kritisiere, sondern auch hier etwas Positives beitrage:

1. Zu Jahresbeginn wird (einmal, aber durchaus wiederholbar) der aktuelle Ferien- und Feiertagskalender geholt.
2. Diese beiden Dateien werden im FHEM-Verzeichnis abgelegt, können von dort aus einmal pro Tag überprüft und ggf. neu geladen werden.

Einen entsprechende Code werde ich in den nächsten Tagen mal hier posten.

LG

pah



Ralli

Ich habe mich genau so klar ausgedrückt. Du musst den Code nicht nehmen und nicht professionell finden - das ist aber egal. Denn jeder kann ihn für sich selbst entweder so nehmen oder umschreiben.
Gruß,
Ralli

Proxmox 8.1 Cluster mit HP ED800G2i7, Intel NUC11TNHi7+NUC7i5BNH, virtualisiertes fhem 6.3 dev, virtualisierte RaspberryMatic (3.75.6.20240316) mit HB-RF-ETH 1.3.0 / RPI-RF-MOD, HM-LAN-GW (1.1.5) und HMW-GW, FRITZBOX 7490 (07.57), FBDECT, Siri und Alexa

kvo1

Hallo Zusammen,
@Ralli , danke !

mir hat das für meine Thematik schon etwas geholfen. Habe die Feier- und Ferientage in meine eigene
owncloud importiert und trage dann bei Bedarf z.b. schulfreien Tage per Hand dazu (okay nicht soooo elegant).

Den Kalender lese ich (zylisch) ein und prüfe ob da ein String "ferien" vorkommt , fülle ein dummy (0 ider 1)
und benutze das dann für weitere Aufgaben (z.B. Jalousiesteuerung) ....leider tut´s noch nicht wirklich  ::)

@pah
ZitatEinen entsprechende Code werde ich in den nächsten Tagen mal hier posten.
würde mich interessieren !

klaus
RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

Prof. Dr. Peter Henning

#7
Mach ich doch glatt.

In myUtils.pm:


sub getCalendar(){
   my $ret;
   my $year=strftime("%Y",localtime);
   $ret = system("wget -O feiertage.ics http://www.schulferien.org/iCal/Feiertage/icals/Feiertage_Baden_Wuerttemberg_".$year.".ics");
   $ret = system("wget -O ferien.ics http://www.schulferien.org/iCal/Ferien/icals/Ferien_Baden_Wuerttemberg_".$year.".ics");
 
};   

sub getDayStatus(){
   my $ret;
   my $msg;
   my @lines;
   my $date;
   my $desc;
   #strftime "%d-%m",localtime
   
   $ret = fhem("get Feiertage text modeAlarmOrStart");
   if( $ret ne ""){
     @lines = split('\n',$ret);
     $date  = substr($lines[0],0,8);
     $desc  = substr($lines[0],15);
     $msg = "$desc $date";
     fhem("set Tagesstatus $desc");
     fhem("set Tagesmode Feiertag");
   }else{
     $ret = fhem("get Ferien text modeAlarmOrStart");
     if( $ret ne ""){
       @lines = split('\n',$ret);
       $date  = substr($lines[0],0,8);
       $desc  = substr($lines[0],15);
       $msg = "$desc $date";
       fhem("set Tagesstatus $desc");
       fhem("set Tagesmode Ferien");
     }else{
       if( strftime("%u",localtime) > 5 ){
         $msg = "Wochenende";
         fhem("set Tagesstatus $msg");
         fhem("set Tagesmode $msg");
       }else{
         $msg = "Arbeitstag";
         fhem("set Tagesstatus $msg");
         fhem("set Tagesmode $msg");
       }
     }
   }
   return $msg;
}

sub checkCalendars($){

  my ($period) = @_;
 
  #-- Start oder Alarm stündlich
  if( ($period eq 'hour') || ($period eq '') ){
    my $text;
    my $hash = $defs{'Termin'};
    $text = fhem("get Muell text modeAlarmOrStart");
    $text = "--" if (!$text);
    $text = "--" if ($text eq "");
    #fhem("set Termin ".$text);
    return $text;
   
  #-- Vorschau täglich oder wenn neu gestartet
  }elsif( ($period eq 'day') || (ReadingsVal("Termin","today",0) eq "today") ){
    my $stoday    = strftime('%2d.%2m.%2y', localtime(time));
    my $stomorrow = strftime('%2d.%2m.%2y', localtime(time+86400));
    my $stwodays  = strftime('%2d.%2m.%2y', localtime(time+2*86400));
    my @today     = ();
    my @tomorrow  = ();
    my @twodays   = ();
    my (@lines,$line,@linarr);
 
    @lines = split('\n',fhem("get Muell text modeAlarmOrStart"));
    foreach $line (@lines){
      #-- line looks as
      #   18.05.15 07:00 Restmüllabfuhr
      chomp($line);
      @linarr = split(' ',$line);
      if( $linarr[0] eq $stoday ){
        push(@today,$linarr[1]." ".$linarr[2]);
      }elsif( $linarr[0] eq $stomorrow ){
        push(@tomorrow,$linarr[1]." ".$linarr[2]);
      }elsif( $linarr[0] eq $stwodays ){
        push(@twodays,$linarr[1]." ".$linarr[2]);
      }     
    }
   
    @lines = split('\n',fhem("get Muell text modeUpcoming"));
    foreach $line (@lines){
      #-- line looks as
      #   18.05.15 07:00 Restmüllabfuhr
      chomp($line);
      @linarr = split(' ',$line);
      if( $linarr[0] eq $stoday ){
        push(@today,$linarr[1]." ".$linarr[2]);
      }elsif( $linarr[0] eq $stomorrow ){
        push(@tomorrow,$linarr[1]." ".$linarr[2]);
      }elsif( $linarr[0] eq $stwodays ){
        push(@twodays,$linarr[1]." ".$linarr[2]);
      }     
    }
    $defs{'Termin'}{READINGS}{'today'}{VAL}    = join(" ",@today);
    $defs{'Termin'}{READINGS}{'tomorrow'}{VAL} = join(" ",@tomorrow);
    $defs{'Termin'}{READINGS}{'twodays'}{VAL}  = join(" ",@twodays);
   
    return "today: ".join(" ",@today)."\ntomorrow: ".join(" ",@tomorrow)."\ntwodays: ".join(" ",@twodays);
  }
}


Die erste Routine wird einmal zu Jahresbeginn gerufen, holt die Ferienkalender. Eine Datei muell.ics wird manuall erzeugt oder sonstwie generiert.

Dann gibt es in den Konfigurationsdateien noch folgende Einträge:


define I.L.morning at *05:00:00 set OWLCD backlight on;;set RixowTab screenBrightness 255;;set Archos7Tab screenBrightness 255;;{getDayStatus()};;
attr I.L.morning group timer
attr I.L.morning room Kontrollraum

define I.L.daybreak at *00:00:10 {checkCalendars('day')}
attr I.L.daybreak group timer
attr I.L.daybreak room Kontrollraum

define I.L.hour at +*01:00:00 set Termin %EVENT
attr I.L.hour alignTime 00:00
attr I.L.hour group timer
attr I.L.hour room Kontrollraum

define Tagesstatus dummy
attr Tagesstatus group Calendar
attr Tagesstatus room Kontrollraum

define Feiertage Calendar ical file feiertage.ics 86400
attr Feiertage room Kontrollraum

define Ferien Calendar ical file ferien.ics 86400
attr Ferien room Kontrollraum

define Tagesmode dummy
attr Tagesmode group Calendar
attr Tagesmode room Kontrollraum

define Muell Calendar ical file muell.ics
attr Muell group Calendar
attr Muell room Kontrollraum

define Termin dummy
attr Termin group Calendar
attr Termin room Kontrollraum
attr Termin stateFormat active
attr Termin userReadings active {checkCalendars('hour')},today:none {'today'},tomorrow:none {'tomorrow'},twodays:none {'twodays'}
attr Termin verbose 1

define Ticker notify Termin:.* {fhem("set RixowTab tickerMessage ".Value('Termin'));;;;fhem("set Archos7Tab tickerMessage ".Value('Termin'))}
attr Ticker group Calendar
attr Ticker room Kontrollraum


Bewirkt, dass einmal zu Tagesbeginn der Tagesstatus gesetzt wird (10 Sekunden nach Mitternacht) sowie einmal zu jeder vollen Stunde auf einen anstehenden Termin überprüft wird.

Die Anzeig ein FHEM ist nicht sehr komfortabel, das läuft bei mir auf einem Tablet an der Wand, das auf einen separaten Apache Web Server zugreift. Dieser hängt (per imagemagick) an ein generiertes Bild ein nettes kleines Icon an - je nachdem entweder eine kleine farbige Mülltonne (je nach Art der Müllabholung), oder so wie hier eine kleine grüne Kiste mit Altpapier ...
(http://oberfl.png)

LG

pah

kvo1

@pah , vielen Dank, werd ich mir mal sehen ...

Wer kann mir kurz auf die Sprünge helfen...

im meinem Kalender "BLN_Ferien" steht im reading "modeStart" für  heute der Text "ferien"  (bzw fe659ee8cf)

über

define BLN_Ferientag dummy
define BLN_Ferien_notify notify BLN_Ferien { fhem "set BLN_Ferientag " . (ReadingsVal("BLN_Ferien", "modeStart", "") =~ "ferien" ? 1: 0) }


soll nun bei der Erkennung des strings "ferien" das dummy auf 0  oder 1 gesetzt werden ! Tut´s aber nicht  :'(

auch das ....

define FBLN_Ferien_notify notify BLN_Ferien:modeStart.* {ReadingsVal("BLN_Ferien", "modeStart", "") =~ "ferien"? fhem("set Ferientag 1"): fhem("set Ferientag 0")}

geht leider nicht ! Wer kann mir kurz helfen ?

Danke vorab !


RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

Ralli

Was ist die Ausgabe, wenn Du


{ fhem "set BLN_Ferientag " . (ReadingsVal("BLN_Ferien", "modeStart", "") =~ "ferien" ? 1: 0) }


bzw. nur mal


{ReadingsVal("BLN_Ferien", "modeStart", "") =~ "ferien" ? 1: 0}


einfach mal in die Eingabe vom Web-Frontend eingibst? Steht nichts im Log?
Gruß,
Ralli

Proxmox 8.1 Cluster mit HP ED800G2i7, Intel NUC11TNHi7+NUC7i5BNH, virtualisiertes fhem 6.3 dev, virtualisierte RaspberryMatic (3.75.6.20240316) mit HB-RF-ETH 1.3.0 / RPI-RF-MOD, HM-LAN-GW (1.1.5) und HMW-GW, FRITZBOX 7490 (07.57), FBDECT, Siri und Alexa

kvo1

RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

kvo1

weiterer Test, wenn ich im Web-Frontend  ...

{ReadingsVal("BLN_Ferien", "modeStart", "")}  eingebe , erhalte ich 1ccee3dd23

Über das Calendar-Device ... ergibt das mittels

get BLN_Ferien text 1ccee3dd23  dann folgendes ... 31.05.15 00:00 ferien

hier geht dann (vermutlich) der Vergleich (=~ "ferien") nicht, weil das ReadingsVal  nicht des String (31.05.15 00:00) liefert , sondern 1ccee3dd23 ... oder ?

Was kann ich tun !?
klaus
RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

Ralli

Da ja nur Ferientage in dem Kalender sein dürften, kannst Du die Abfrage einfach umdrehen. Wenn nichts im Reading modeStart drin steht, ist auch kein Ferientag.


{ fhem "set BLN_Ferientag " . (ReadingsVal("BLN_Ferien", "modeStart", "") ne "" ? 1: 0) }
Gruß,
Ralli

Proxmox 8.1 Cluster mit HP ED800G2i7, Intel NUC11TNHi7+NUC7i5BNH, virtualisiertes fhem 6.3 dev, virtualisierte RaspberryMatic (3.75.6.20240316) mit HB-RF-ETH 1.3.0 / RPI-RF-MOD, HM-LAN-GW (1.1.5) und HMW-GW, FRITZBOX 7490 (07.57), FBDECT, Siri und Alexa

kvo1

wenn ich das so angeben
define BLN_Ferien_notify notify BLN_Ferien:modeStart:.* { fhem "set BLN_Ferientag " . (ReadingsVal("BLN_Ferien", "modeStart", "") =~ "1ccee3dd23" ? 1: 0) }

wird das dummy "BLN_Ferientag"   auf 1  gesetzt !

Problem ist nur das sich dies ja immer ändert ... , auch bei gleichen Einträgen ..
also im Kalender gelöscht , gleichen Eintrag wiederholt ..... jetzt steht da  40af736c3c

klaus
RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB

kvo1

Hallo Ralli,

Zitat von: Ralli am 31 Mai 2015, 20:54:18
Da ja nur Ferientage in dem Kalender sein dürften, kannst Du die Abfrage einfach umdrehen. Wenn nichts im Reading modeStart drin steht, ist auch kein Ferientag.


{ fhem "set BLN_Ferientag " . (ReadingsVal("BLN_Ferien", "modeStart", "") ne "" ? 1: 0) }


super das geht und man kann sogar "irgendwas" reinschreiben ohne auf den korrekten Text ("ferien") zu achten. Ein Plus für WAF  ;)

Danke nochmal für die Hilfe ...!

Gruss
Klaus
RPi1: mit CUL: HM-CC-RT-DN,HM-ES-PMSw1-Pl,HM-LC-BL1-FM,HM-LC-Bl1PBU-FM,HM-LC-SW1-PL2,HM-SCI-3-FM,HM-SEC-SC-2,KFM-Sensor
RPi2: Viessmann(optolink) mit 99_VCONTROL.pm,
Cubietruck: Wheezy / Apache / Owncloud
Cubietruck: Armbian(Jessie) / fhem 5.7 / LMS 7.9
RPi3: (Test) mit 7" Touch  &  HM-MOD-RPI-PCB