DOIF für "Social" Seasons (zB Weihnachtszeit, Osterzeit, Karneval etc.)

Begonnen von Loredo, 07 November 2015, 17:46:24

Vorheriges Thema - Nächstes Thema

Damian

Das Problem bei der Definition von Loredo ist die Tatsache, dass er die DOIF-Syntax etwas "missbraucht" hat. Er hat in den Bedingungen eines DOIFs ganze Perl-Programme untergebracht. Das ist nirgendwo dokumentiert, es kann gut funktionieren oder irgendwann durch ein Update auch nicht mehr.

Übrigens steht in der Fehlermeldung:  Undefined subroutine &main::str2time 

Dann ist wohl klar was hier fehlt.

Die Definition ist hier nicht gut strukturiert, da immer Wiederholungen programmiert wurden, die unnötig den Code aufblähen. Dieser Fall wäre prädestiniert für DOIF-Perl. Dort lassen sich Routinen, die im Device immer wieder benötigt werden, im DOIF-Device selbst gekapselt definieren.

Für ein eigenständiges FHEM-Modul finde ich die Problematik wiederum zu banal. Gleichzeitig wäre ein eigenes Modul von Usern schlecht erweiterbar.

Wenn ich heute Zeit finde, dann bastle ich euch eine adäquate Lösung in DOIF-Perl, die im Gegensatz zu einem eigenständigen FHEM-Modul von Usern für ihre Zwecke leicht erweiterbar wäre.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Clyde

Ich wollte für eine Email-Subject-Zeile immer ein passendes Icon ausgewählt haben, was auch die Feiertage berücksichtigt.

Die SuFu hatte mich hierher geführt. Vielen Dank für die Antworten. Ich habe mir schließlich in Anlehnung an den DOIF-Code folgende Perl-sub gebastelt, die mir genügt und evtl. anderen als Vorlage dienen kann:


sub my_subject() {

  my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time);
  $year += 1900;

  my ( $monEaster, $mdayEaster) = western_easter($year);
  my $carnivalMon = str2time("$year-$monEaster-$mdayEaster") - 47*86400;
  my $carnivalTue = $carnivalMon + 86400;
  my ( $secB, $minB, $hourB, $mdayB, $monB, $yearB, $wdayB, $ydayB, $isdstB ) = localtime($carnivalMon);
  my ( $secE, $minE, $hourE, $mdayE, $monE, $yearE, $wdayE, $ydayE, $isdstE ) = localtime($carnivalTue);

  my $carnivalEnd = str2time("$year-$monEaster-$mdayEaster") - 46*86400;
  my $carnivalStart = $carnivalEnd - 5*86400;

  my $fastEnd = str2time("$year-$monEaster-$mdayEaster") - 2*86400;
  my $fastStart = $fastEnd - 43*86400;

  my ( $monB, $mdayB) = western_easter($year);
  my $easterTimeBegin = $mdayB - 1;

  my $pentecostSat = str2time("$year-$monEaster-$mdayEaster") + 48*86400;
  my $pentecostMon = $pentecostSat + 2*86400;

  my $midSept = str2time("$year-09-15");
  my ( $secS, $minS, $hourS, $mdayS, $monS, $yearS, $wdayS, $ydayS, $isdstS ) = localtime($midSept);

  my $wiesnBegin = $midSept + $wdayS*86400;
  my $wiesnEnd = $wiesnBegin + 21*86400;

  my $christmas = str2time("$year-12-25");
  my ( $secC, $minC, $hourC, $mdayC, $monC, $yearC, $wdayC, $ydayC, $isdstC ) = localtime($christmas);
  my $adventBegin = $christmas - ($wdayC+21)*86400;
  my ( $sec2, $min2, $hour2, $mday2, $mon2, $year2, $wday2, $yday2, $isdst2 ) = localtime($adventBegin);

  my $subject;
  my $saisonal = "nix";


## Carnival: Carnival Mon/Tue and Valentine's Day at the same day
{if   ($mon eq 1 and  $mday eq 14 and  ($mday eq $mdayB or $mday eq $mdayE))
      {$saisonal = "Karneval"; $subject = '👹 ';}
## Valentine's Day
elsif ($mon eq 1 and  $mday eq 14)
      {$saisonal = "Valentin"; $subject = '💘 ';}
## Carnival: Mon+Tue
elsif ($mday eq $mdayB or $mday eq $mdayE)
      {$saisonal = "Karneval"; $subject = '👹 ';}
else {
## Carnival: Thursday before Ash Wednesday until day before Ash Wednesday w/o Valentine's Day
  $carnivalEnd = str2time("$year-$monEaster-$mdayEaster") - 46*86400;
  $carnivalStart = $carnivalEnd - 5*86400;
  ( $secB, $minB, $hourB, $mdayB, $monB, $yearB, $wdayB, $ydayB, $isdstB ) = localtime($carnivalStart);
  ( $secE, $minE, $hourE, $mdayE, $monE, $yearE, $wdayE, $ydayE, $isdstE ) = localtime($carnivalEnd);

{if  (($mon eq $monB and $mday ge $mdayB) or
      ($mon eq $monE and $mday le $mdayE))
     {$saisonal = "Karneval"; $subject = '👺 ';}
else {
  $fastEnd = str2time("$year-$monEaster-$mdayEaster") - 2*86400;
  $fastStart = $fastEnd - 43*86400;
  ( $secB, $minB, $hourB, $mdayB, $monB, $yearB, $wdayB, $ydayB, $isdstB ) = localtime($fastStart);
  ( $secE, $minE, $hourE, $mdayE, $monE, $yearE, $wdayE, $ydayE, $isdstE ) = localtime($fastEnd);

## Fasting/Strong-Beer Time: Ash Wednesday until Good Friday
{if  (
  ($mon eq $monB and $mday ge $mdayB) and
  ($mon eq $monE and $mday le $mdayE)
     )
     {$saisonal = "Starkbierzeit"; $subject = '🍺 ';}
else {
  ( $monB, $mdayB) = western_easter($year);
  $easterTimeBegin = $mdayB - 1;

## Easter Time: Starts Easter Saturday, ends Apr 29th
{if  (
  ($mon eq $monB and $mday ge $easterTimeBegin) or
  ($mon eq 3 and $mday ge 25 and $mday le 29)
     )
     {$saisonal = "Osterzeit"; $subject = '🐇 ';}
else {
  ( $monB, $mdayB) = western_easter($year);
  $easterTimeBegin = $mdayB - 1;

## May Festival: Apr 30th and May 1st
{if  (
  ($mon eq 3 and $mday eq 30) or
  ($mon eq 4 and $mday eq 1)
     )
     {$saisonal = "Tanz in den Mai"; $subject = '👗 ';}
else {
  $pentecostSat = str2time("$year-$monEaster-$mdayEaster") + 48*86400;
  $pentecostMon = $pentecostSat + 2*86400;
  ( $secB, $minB, $hourB, $mdayB, $monB, $yearB, $wdayB, $ydayB, $isdstB ) = localtime($pentecostSat);
  ( $secE, $minE, $hourE, $mdayE, $monE, $yearE, $wdayE, $ydayE, $isdstE ) = localtime($pentecostMon);

## Pentecost: Saturday til Monday
{if  (
  ($mon eq $monB and $mday ge $mdayB) and
  ($mon eq $monE and $mday le $mdayE)
     )
     {$saisonal = "Pfingsten"; $subject = '👻 ';}
else {
  $midSept = str2time("$year-09-15");
  ( $secS, $minS, $hourS, $mdayS, $monS, $yearS, $wdayS, $ydayS, $isdstS ) = localtime($midSept);
  if ($wdayS eq 6) {
    $wdayS = 7;
  } elsif ($wdayS eq 0) {
    $wdayS = 6;
  } elsif ($wdayS eq 1) {
    $wdayS = 5;
  } elsif ($wdayS eq 2) {
    $wdayS = 4;
  } elsif ($wdayS eq 3) {
    $wdayS = 3;
  } elsif ($wdayS eq 4) {
    $wdayS = 2;
  } elsif ($wdayS eq 5) {
    $wdayS = 1;
  };
  $wiesnBegin = $midSept + $wdayS*86400;
  $wiesnEnd = $wiesnBegin + 21*86400;
  ( $secB, $minB, $hourB, $mdayB, $monB, $yearB, $wdayB, $ydayB, $isdstB ) = localtime($wiesnBegin);
  ( $secE, $minE, $hourE, $mdayE, $monE, $yearE, $wdayE, $ydayE, $isdstE ) = localtime($wiesnEnd);

## Oktoberfest: Saturday after Sept 15th for 3 weeks
{if  (
  ($mon eq $monB and $mday ge $mdayB) and
  ($mon eq $monE and $mday le $mdayE)
     )
     {$saisonal = "Wiesn"; $subject = '🍺 ';}
else {

## Harvest festival: 1st sunday in Oct
{if  (
  $mon eq 9 and
  $mday le 7 and
  $wday eq 0
     )
     {$saisonal = "Erntedank"; $subject = '🌾 ';}
else {

## Halloween Week: Oct 24th until Otc 30th
{if  (
  $mon eq 9 and
  $mday ge 24 and
  $mday le 30
     )
     {$saisonal = "Halloweenwoche"; $subject = '🎃 ';}
else {

## Halloween: Oct 31th and Nov 1st
{if  (
  ($mon eq 9 and $mday eq 31) or
  ($mon eq 10 and $mday eq 1)
     )
     {$saisonal = "Halloween"; $subject = '🎃 ';}
else {

## St. Martin's Day: Nov 11th
{if  (
  ($mon eq 10 and $mday eq 11)
     )
     {$saisonal = "Martinstag"; $subject = '🌜 ';}
else {
  $christmas = str2time("$year-12-25");
  ( $secC, $minC, $hourC, $mdayC, $monC, $yearC, $wdayC, $ydayC, $isdstC ) = localtime($christmas);
  $wdayC = $wdayC ? $wdayC : 7;
  $adventBegin = $christmas - ($wdayC+21)*86400;
  ( $sec2, $min2, $hour2, $mday2, $mon2, $year2, $wday2, $yday2, $isdst2 ) = localtime($adventBegin);

## Christmas time: Starts 1st Advent, ends Dec 30th
{if  (
  ($mon eq $mon2 and $mday ge $mday2) or
  ($mon eq 11 and $mday le 30)
     )
     {$saisonal = "Adventszeit"; $subject = '🎄 ';}
else {

## New Year: Dec 31st and Jan 1st
{if  (
  ($mon eq 11 and $mday eq 31)
     )
     {$saisonal = "Sylvester"; $subject = '🚀 ';}

elsif  (
  ($mon eq 0 and $mday eq 1)
     )
     {$saisonal = "Neujahr"; $subject = '✨ ';}
};

}};
}};
}};
}};
}};
}};
}};
}};
}};
}};
}};
}};


{if ($saisonal == "nix" or $wday == 2){
#Saisonal
if   ($yday >   1 and $yday <=  20){$subject = '🎿 '.$subject; $saisonal = "Winter";}
elsif($yday >  31 and $yday <=  45){$subject = '💘 '.$subject; $saisonal = "Valentin";}
elsif($yday >  20 and $yday <=  40){$subject = '⛄ '.$subject; $saisonal = "Winter";}
elsif($yday >  40 and $yday <=  60){$subject = '❆ '.$subject; $saisonal = "Winter";}
elsif($yday >  60 and $yday <=  80){$subject = '🐑 '.$subject; $saisonal = "Schafe";}
elsif($yday >  80 and $yday <=  90){$subject = '🎢 '.$subject; $saisonal = "Hamburger Frühlingsdom";}
elsif($yday >  90 and $yday <= 100){$subject = '🎡 '.$subject; $saisonal = "Osterwiese";}
elsif($yday > 100 and $yday <= 110){$subject = '🚴 '.$subject; $saisonal = "Radtour";}
elsif($yday > 110 and $yday <= 120){$subject = '🌼 '.$subject; $saisonal = "Frühling";}
elsif($yday > 120 and $yday <= 130){$subject = '🍦 '.$subject; $saisonal = "Eis";}
elsif($yday > 130 and $yday <= 140){$subject = '🍓 '.$subject; $saisonal = "Erdbeeren";}
elsif($yday > 140 and $yday <= 150){$subject = '🚴 '.$subject; $saisonal = "Radtour";}
elsif($yday > 150 and $yday <= 160){$subject = '🍦 '.$subject; $saisonal = "Eis";}
elsif($yday > 160 and $yday <= 170){$subject = '🚴 '.$subject; $saisonal = "Radtour";}
elsif($yday > 170 and $yday <= 180){$subject = '👙 '.$subject; $saisonal = "Sommer";}
elsif($yday > 180 and $yday <= 190){$subject = '🍅 '.$subject; $saisonal = "Tomatenzeit";}
elsif($yday > 190 and $yday <= 200){$subject = '⚓ '.$subject; $saisonal = "Cuxhaven";}
elsif($yday > 200 and $yday <= 210){$subject = '🍉 '.$subject; $saisonal = "Melonenzeit";}
elsif($yday > 210 and $yday <= 220){$subject = '🚴 '.$subject; $saisonal = "Radtour";}
elsif($yday > 220 and $yday <= 230){$subject = '🚗 '.$subject;  $saisonal = "Magdeburg";}
elsif($yday > 230 and $yday <= 240){$subject = '🍅 '.$subject; $saisonal = "Tomaten";}
elsif($yday > 240 and $yday <= 250){$subject = '🌻 '.$subject; $saisonal = "Spätsommer";}
elsif($yday > 250 and $yday <= 270){$subject = '👗 '.$subject; $saisonal = "Stoffmarkt";}
elsif($yday > 270 and $yday <= 280){$subject = '🍁 '.$subject; $saisonal = "Herbst";}
elsif($yday > 280 and $yday <= 290){$subject = '🎡 '.$subject; $saisonal = "Freimarkt";}
elsif($yday > 290 and $yday <= 305){$subject = '🎃 '.$subject; $saisonal = "Kürbisernte";}
elsif($yday > 305 and $yday <= 315){$subject = '🎢 '.$subject; $saisonal = "Hamburger Herbstdom";}
elsif($yday > 315 and $yday <= 330){$subject = '🛁 '.$subject; $saisonal = "Wannenbad";}
elsif($yday > 330 and $yday <= 340){$subject = '🎄 '.$subject; $saisonal = "Adventszeit";}
elsif($yday > 340 and $yday <= 350){$subject = '🎄 '.$subject; $saisonal = "Adventszeit";}
elsif($yday > 350 and $yday <= 361){$subject = '🎅 '.$subject; $saisonal = "Weihnachten";}
elsif($yday > 361 and $yday <= 365){$subject = '🚀 '.$subject; $saisonal = "Sylvester";}
}};

fhem "set Test  $subject $saisonal";
}
2x Cubietruck, CUL868, HM-USB-CFG2
FS20, FHT, KS300, HM, MAX, Tradfri

ThoTo

Zitat von: Damian am 02 September 2018, 10:47:06
Wenn ich heute Zeit finde, dann bastle ich euch eine adäquate Lösung in DOIF-Perl, die im Gegensatz zu einem eigenständigen FHEM-Modul von Usern für ihre Zwecke leicht erweiterbar wäre.

Danke, Damian  8) 8) 8)
KNX | MQTT | Docker | Sonos | FHEMapp

"Zwei Dinge sind unendlich, das Universum und die menschliche Dummheit, aber bei dem Universum bin ich mir noch nicht ganz sicher." (Albert Einstein)

Damian

Ich habe ausgehend vom Code von Clyde eine DOIF-Version gebaut, die im Status Season angibt und im  Reading subject das entsprechende Icon.

Beim Antesten sind mir in beiden Versionen Fehler aufgefallen (die habe ich korrigiert), ich schließe allerdings nicht aus, dass noch mehr Fehler drin stecken.

Hier die Rawdefinition:

defmod SocialSeason2 DOIF subs {\
sub my_subject() {\
\
  my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time);;\
  #my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(str2time"2018-12-1");;\
\
  $year += 1900;;\
\
  my ( $monEaster, $mdayEaster) = western_easter($year);;\
  my $carnivalMon = str2time("$year-$monEaster-$mdayEaster") - 47*86400;;\
  my $carnivalTue = $carnivalMon + 86400;;\
  my ( $secB, $minB, $hourB, $mdayB, $monB, $yearB, $wdayB, $ydayB, $isdstB ) = localtime($carnivalMon);;\
  my ( $secE, $minE, $hourE, $mdayE, $monE, $yearE, $wdayE, $ydayE, $isdstE ) = localtime($carnivalTue);;\
\
  my $carnivalEnd = str2time("$year-$monEaster-$mdayEaster") - 46*86400;;\
  my $carnivalStart = $carnivalEnd - 5*86400;;\
\
  my $fastEnd = str2time("$year-$monEaster-$mdayEaster") - 2*86400;;\
  my $fastStart = $fastEnd - 43*86400;;\
\
  my ( $monB, $mdayB) = western_easter($year);;\
  my $easterTimeBegin = $mdayB - 1;;\
\
  my $pentecostSat = str2time("$year-$monEaster-$mdayEaster") + 48*86400;;\
  my $pentecostMon = $pentecostSat + 2*86400;;\
\
  my $midSept = str2time("$year-09-15");;\
  my ( $secS, $minS, $hourS, $mdayS, $monS, $yearS, $wdayS, $ydayS, $isdstS ) = localtime($midSept);;\
\
  my $wiesnBegin = $midSept + $wdayS*86400;;\
  my $wiesnEnd = $wiesnBegin + 21*86400;;\
\
  my $christmas = str2time("$year-12-25");;\
  my ( $secC, $minC, $hourC, $mdayC, $monC, $yearC, $wdayC, $ydayC, $isdstC ) = localtime($christmas);;\
  my $adventBegin = $christmas - ($wdayC+21)*86400;;\
  my ( $sec2, $min2, $hour2, $mday2, $mon2, $year2, $wday2, $yday2, $isdst2 ) = localtime($adventBegin);;\
\
  my $subject;;\
  my $saisonal = "nix";;\
\
\
## Carnival: Carnival Mon/Tue and Valentine's Day at the same day\
{if   ($mon eq 1 and  $mday eq 14 and  ($mday eq $mdayB or $mday eq $mdayE))\
      {$saisonal = "Karneval";; $subject = '👹 ';;}\
## Valentine's Day\
elsif ($mon eq 1 and  $mday eq 14)\
      {$saisonal = "Valentin";; $subject = '💘 ';;}\
## Carnival: Mon+Tue\
elsif ($mday eq $mdayB or $mday eq $mdayE)\
      {$saisonal = "Karneval";; $subject = '👹 ';;}\
else {\
## Carnival: Thursday before Ash Wednesday until day before Ash Wednesday w/o Valentine's Day\
  $carnivalEnd = str2time("$year-$monEaster-$mdayEaster") - 46*86400;;\
  $carnivalStart = $carnivalEnd - 5*86400;;\
  ( $secB, $minB, $hourB, $mdayB, $monB, $yearB, $wdayB, $ydayB, $isdstB ) = localtime($carnivalStart);;\
  ( $secE, $minE, $hourE, $mdayE, $monE, $yearE, $wdayE, $ydayE, $isdstE ) = localtime($carnivalEnd);;\
\
{if  (($mon eq $monB and $mday ge $mdayB) or\
      ($mon eq $monE and $mday le $mdayE))\
     {$saisonal = "Karneval";; $subject = '👺 ';;}\
else {\
  $fastEnd = str2time("$year-$monEaster-$mdayEaster") - 2*86400;;\
  $fastStart = $fastEnd - 43*86400;;\
  ( $secB, $minB, $hourB, $mdayB, $monB, $yearB, $wdayB, $ydayB, $isdstB ) = localtime($fastStart);;\
  ( $secE, $minE, $hourE, $mdayE, $monE, $yearE, $wdayE, $ydayE, $isdstE ) = localtime($fastEnd);;\
\
## Fasting/Strong-Beer Time: Ash Wednesday until Good Friday\
{if  (\
  ($mon eq $monB and $mday ge $mdayB) and\
  ($mon eq $monE and $mday le $mdayE)\
     )\
     {$saisonal = "Starkbierzeit";; $subject = '🍺 ';;}\
else {\
  ( $monB, $mdayB) = western_easter($year);;\
  $easterTimeBegin = $mdayB - 1;;\
\
## Easter Time: Starts Easter Saturday, ends Apr 29th\
{if  (\
  ($mon eq $monB and $mday ge $easterTimeBegin) or\
  ($mon eq 3 and $mday ge 25 and $mday le 29)\
     )\
     {$saisonal = "Osterzeit";; $subject = '🐇 ';;}\
else {\
  ( $monB, $mdayB) = western_easter($year);;\
  $easterTimeBegin = $mdayB - 1;;\
\
## May Festival: Apr 30th and May 1st\
{if  (\
  ($mon eq 3 and $mday eq 30) or\
  ($mon eq 4 and $mday eq 1)\
     )\
     {$saisonal = "Tanz in den Mai";; $subject = '👗 ';;}\
else {\
  $pentecostSat = str2time("$year-$monEaster-$mdayEaster") + 48*86400;;\
  $pentecostMon = $pentecostSat + 2*86400;;\
  ( $secB, $minB, $hourB, $mdayB, $monB, $yearB, $wdayB, $ydayB, $isdstB ) = localtime($pentecostSat);;\
  ( $secE, $minE, $hourE, $mdayE, $monE, $yearE, $wdayE, $ydayE, $isdstE ) = localtime($pentecostMon);;\
\
## Pentecost: Saturday til Monday\
{if  (\
  ($mon eq $monB and $mday ge $mdayB) and\
  ($mon eq $monE and $mday le $mdayE)\
     )\
     {$saisonal = "Pfingsten";; $subject = '👻 ';;}\
else {\
  $midSept = str2time("$year-09-15");;\
  ( $secS, $minS, $hourS, $mdayS, $monS, $yearS, $wdayS, $ydayS, $isdstS ) = localtime($midSept);;\
  if ($wdayS eq 6) {\
    $wdayS = 7;;\
  } elsif ($wdayS eq 0) {\
    $wdayS = 6;;\
  } elsif ($wdayS eq 1) {\
    $wdayS = 5;;\
  } elsif ($wdayS eq 2) {\
    $wdayS = 4;;\
  } elsif ($wdayS eq 3) {\
    $wdayS = 3;;\
  } elsif ($wdayS eq 4) {\
    $wdayS = 2;;\
  } elsif ($wdayS eq 5) {\
    $wdayS = 1;;\
  };;\
  $wiesnBegin = $midSept + $wdayS*86400;;\
  $wiesnEnd = $wiesnBegin + 21*86400;;\
  ( $secB, $minB, $hourB, $mdayB, $monB, $yearB, $wdayB, $ydayB, $isdstB ) = localtime($wiesnBegin);;\
  ( $secE, $minE, $hourE, $mdayE, $monE, $yearE, $wdayE, $ydayE, $isdstE ) = localtime($wiesnEnd);;\
\
## Oktoberfest: Saturday after Sept 15th for 3 weeks\
{if  (\
  ($mon eq $monB and $mday ge $mdayB) and\
  ($mon eq $monE and $mday le $mdayE)\
     )\
     {$saisonal = "Wiesn";; $subject = '🍺 ';;}\
else {\
\
## Harvest festival: 1st sunday in Oct\
{if  (\
  $mon eq 9 and\
  $mday le 7 and\
  $wday eq 0\
     )\
     {$saisonal = "Erntedank";; $subject = '🌾 ';;}\
else {\
\
## Halloween Week: Oct 24th until Otc 30th\
{if  (\
  $mon eq 9 and\
  $mday ge 24 and\
  $mday le 30\
     )\
     {$saisonal = "Halloweenwoche";; $subject = '🎃 ';;}\
else {\
\
## Halloween: Oct 31th and Nov 1st\
{if  (\
  ($mon eq 9 and $mday eq 31) or\
  ($mon eq 10 and $mday eq 1)\
     )\
     {$saisonal = "Halloween";; $subject = '🎃 ';;}\
else {\
\
## St. Martin's Day: Nov 11th\
{if  (\
  ($mon eq 10 and $mday eq 11)\
     )\
     {$saisonal = "Martinstag";; $subject = '🌜 ';;}\
else {\
  $christmas = str2time("$year-12-25");;\
  ( $secC, $minC, $hourC, $mdayC, $monC, $yearC, $wdayC, $ydayC, $isdstC ) = localtime($christmas);;\
  $wdayC = $wdayC ? $wdayC : 7;;\
  $adventBegin = $christmas - ($wdayC+21)*86400;;\
  ( $sec2, $min2, $hour2, $mday2, $mon2, $year2, $wday2, $yday2, $isdst2 ) = localtime($adventBegin);;\
\
## Christmas time: Starts 1st Advent, ends Dec 30th\
{if  (\
  ($mon eq $mon2 and $mday ge $mday2) and\
  ($mon eq 11 and $mday le 30)\
     )\
     {$saisonal = "Adventszeit";; $subject = '🎄 ';;}\
else {\
\
## New Year: Dec 31st and Jan 1st\
{if  (\
  ($mon eq 11 and $mday eq 31) \
     )\
     {$saisonal = "Sylvester";; $subject = '🚀 ';;}\
\
elsif  (\
  ($mon eq 0 and $mday eq 1)\
     )\
     {$saisonal = "Neujahr";; $subject = '✨ ';;}\
};;\
\
}};;\
}};;\
}};;\
}};;\
}};;\
}};;\
}};;\
}};;\
}};;\
}};;\
}};;\
}};;\
\
\
{if ($saisonal eq "nix" or $wday == 2){\
#Saisonal\
if   ($yday >   1 and $yday <=  20){$subject = '🎿 '.$subject;; $saisonal = "Winter";;}\
elsif($yday >  31 and $yday <=  45){$subject = '💘 '.$subject;; $saisonal = "Valentin";;}\
elsif($yday >  20 and $yday <=  40){$subject = '⛄ '.$subject;; $saisonal = "Winter";;}\
elsif($yday >  40 and $yday <=  60){$subject = '❆ '.$subject;; $saisonal = "Winter";;}\
elsif($yday >  60 and $yday <=  80){$subject = '🐑 '.$subject;; $saisonal = "Schafe";;}\
elsif($yday >  80 and $yday <=  90){$subject = '🎢 '.$subject;; $saisonal = "Hamburger Frühlingsdom";;}\
elsif($yday >  90 and $yday <= 100){$subject = '🎡 '.$subject;; $saisonal = "Osterwiese";;}\
elsif($yday > 100 and $yday <= 110){$subject = '🚴 '.$subject;; $saisonal = "Radtour";;}\
elsif($yday > 110 and $yday <= 120){$subject = '🌼 '.$subject;; $saisonal = "Frühling";;}\
elsif($yday > 120 and $yday <= 130){$subject = '🍦 '.$subject;; $saisonal = "Eis";;}\
elsif($yday > 130 and $yday <= 140){$subject = '🍓 '.$subject;; $saisonal = "Erdbeeren";;}\
elsif($yday > 140 and $yday <= 150){$subject = '🚴 '.$subject;; $saisonal = "Radtour";;}\
elsif($yday > 150 and $yday <= 160){$subject = '🍦 '.$subject;; $saisonal = "Eis";;}\
elsif($yday > 160 and $yday <= 170){$subject = '🚴 '.$subject;; $saisonal = "Radtour";;}\
elsif($yday > 170 and $yday <= 180){$subject = '👙 '.$subject;; $saisonal = "Sommer";;}\
elsif($yday > 180 and $yday <= 190){$subject = '🍅 '.$subject;; $saisonal = "Tomatenzeit";;}\
elsif($yday > 190 and $yday <= 200){$subject = '⚓ '.$subject;; $saisonal = "Cuxhaven";;}\
elsif($yday > 200 and $yday <= 210){$subject = '🍉 '.$subject;; $saisonal = "Melonenzeit";;}\
elsif($yday > 210 and $yday <= 220){$subject = '🚴 '.$subject;; $saisonal = "Radtour";;}\
elsif($yday > 220 and $yday <= 230){$subject = '🚗 '.$subject;;  $saisonal = "Magdeburg";;}\
elsif($yday > 230 and $yday <= 240){$subject = '🍅 '.$subject;; $saisonal = "Tomaten";;}\
elsif($yday > 240 and $yday <= 250){$subject = '🌻 '.$subject;; $saisonal = "Spätsommer";;}\
elsif($yday > 250 and $yday <= 270){$subject = '👗 '.$subject;; $saisonal = "Stoffmarkt";;}\
elsif($yday > 270 and $yday <= 280){$subject = '🍁 '.$subject;; $saisonal = "Herbst";;}\
elsif($yday > 280 and $yday <= 290){$subject = '🎡 '.$subject;; $saisonal = "Freimarkt";;}\
elsif($yday > 290 and $yday <= 305){$subject = '🎃 '.$subject;; $saisonal = "Kürbisernte";;}\
elsif($yday > 305 and $yday <= 315){$subject = '🎢 '.$subject;; $saisonal = "Hamburger Herbstdom";;}\
elsif($yday > 315 and $yday <= 330){$subject = '🛁 '.$subject;; $saisonal = "Wannenbad";;}\
elsif($yday > 330 and $yday <= 340){$subject = '🎄 '.$subject;; $saisonal = "Adventszeit";;}\
elsif($yday > 340 and $yday <= 350){$subject = '🎄 '.$subject;; $saisonal = "Adventszeit";;}\
elsif($yday > 350 and $yday <= 361){$subject = '🎅 '.$subject;; $saisonal = "Weihnachten";;}\
elsif($yday > 361 and $yday <= 365){$subject = '🚀 '.$subject;; $saisonal = "Sylvester";;}\
}};;\
return "$subject $saisonal";;\
}\
\
}\
\
{\
  if ([00:00]) {\
    my ($subject,$saisonal)=split(" ",my_subject());;\
    set_Reading ("state",$saisonal,1);;\
    set_Reading ("subject",$subject,1);;\
  }\
}

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

rischbiter123

Erst mal vielen Dank für die Arbeit. Allerdings habe ich noch eine Frage. Kann man Definitionen, die man nicht braucht (z.B. Oktoberfest) einfach löschen, oder muss man noch andere Teile auskommentieren?

LG

Andreas
4*Raspi, Max Thermostate und Fensterkontakte, FB7590, Mysensors und NanoCUL, IT und Sonoff, zigbee2mqtt2

Damian

Zitat von: rischbiter123 am 08 September 2018, 21:52:14
Erst mal vielen Dank für die Arbeit. Allerdings habe ich noch eine Frage. Kann man Definitionen, die man nicht braucht (z.B. Oktoberfest) einfach löschen, oder muss man noch andere Teile auskommentieren?

LG

Andreas

Es ist eine programmierte Lösung. Man kann alles ändern bzw. herausnehmen, solange der Perl-Code funktioniert :)

Das ist auch gleichzeitig der Nachteil dieser Lösungen, weil sie nicht gut konfigurierbar sind.

Es meiner Sicht kann man die meisten Dinge genau so gut in einer holiday-Datei definieren.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

Hier eine Version, die leicht konfigurierbar ist und flexibler mit Intervallen umgehen kann als holiday:

defmod SocialSeason2 DOIF init {\
$_season{Ostern}="E+0 E+1";;\
$_season{"1. Mai"}="05-01";;\
$_season{Weihnachten}="12-25 12-26";;\
$_season{Advent}="A+0 A+21";;\
}\
\
{\
  if ([00:00]) {\
    my $season=myseason(split("-",$ymd,2));;\
    set_Reading ("state",$season,1);;\
  }\
}\
\
subs {\
sub myseason {\
my ($year,$md)=@_;;\
my $from;;\
my $to;;\
my ( $monEaster, $mdayEaster) = western_easter($year);;\
my $easter=str2time("$year-$monEaster-$mdayEaster");;\
\
my $christmas = str2time("$year-12-25");;\
my ( $secC, $minC, $hourC, $mdayC, $monC, $yearC, $wdayC, $ydayC, $isdstC ) = localtime(str2time("$year-12-25"));;\
$wdayC = $wdayC ? $wdayC : 7;;\
my $adventBegin = $christmas - ($wdayC+21)*86400;;\
\
\
foreach my $key (keys %{$_season}) {\
  ($from,$to)=split (' ',$_season{$key});;\
  if ($from =~ /E((\+|\-)\d+)/) {\
    my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime ($easter + $1*86400);;   \
    $from=sprintf("%02d-%02d",$mon+1,$mday);;\
  } elsif ($from =~ /A((\+|\-)\d+)/) {\
    my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime ($adventBegin + $1*86400);;   \
    $from=sprintf("%02d-%02d",$mon+1,$mday);;\
  }\
\
  if (defined $to) {\
    if ($to =~ /E((\+|\-)\d+)/) {\
      my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime ($easter + $1*86400);;   \
      $to=sprintf("%02d-%02d",$mon+1,$mday);;\
    } elsif ($to =~ /A((\+|\-)\d+)/) {\
      my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime ($adventBegin + $1*86400);;   \
      $to=sprintf("%02d-%02d",$mon+1,$mday);;\
    }\
  }\
  if (!defined ($to) and $from eq $md or (defined ($to) and $md ge $from and $md le $to)) {\
    return"$key";;\
  } \
}\
return ("none");;\
}\
}\


Im init-Block können einzelne Tage im Format MM-DD oder Zeitintervalle von bis im Format MM-DD MM-DD definiert werden.

Eine Besonderheit ist der Buchstabe E für Ostersonntag und A für 1. Advent, diese Angaben können mit Addition oder Subtraktion einer Zahl statt MM-DD angegeben werden.

$_season{Ostern}="E+0 E+1" bedeutet Ostersonntag bis Ostermontag -> Ostern
$_season{Advent}="A+0 A+21" bedeutet vom ersten bis zum vierten Adventsonntag

Der init-Block lässt sich beliebig erweitern. Das Schlüsselwort in geschweiften Klammern kann frei gewählt werden und ist gleichzeitig der Status des Moduls in der jeweiligen Zeit, sonst steht da "none".

Beispiel für Karneval (von Weiberfastnacht bis Fastnacht) wäre:

$_season{Kerneval}="E-51 E-46" Weiberfastnacht ist 51 Tage vor Ostersonntag und Fastnacht ist 46 Tage vor Ostersonntag.




Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

Es ist mir aufgefallen, dass bei überschneidenden Einträgen, die Eindeutigkeit der Definition nicht gegeben war, weil das Auslesen eines Hashes keine eindeutige Reihenfolge hat. Ich habe die Definition auf Array umgestellt, gleichzeitig ist die Konfiguration noch einfacher geworden. Sie wird zeilenweise innerhalb von $_season definiert (sie könnte auch aus einer Datei kommen).
Hier die neue Version:

Syntax:
<from> <to>, <designation> oder <date>, <designation>

defmod SocialSeason2 DOIF init {
$_season="
E-10 E+1,    Ostern
05-01,       1. Mai
12-25 12-26, Weihnachten
A+0,         1. Advent
A+7,         2. Advent
A+14,        3. Advent
A+21,        4. Advent
A+0 A+21,    Adventszeit
E-51 E-46,   Karneval
";
}

{
  if ([00:00]) {
    my $season=myseason(split("-",$ymd,2));
    set_Reading ("state",$season,1);
  }
}

subs {
sub myseason {
my ($year,$md)=@_;
my $from;
my $to;
my $date;
my $token;
my ( $monEaster, $mdayEaster) = western_easter($year);
my $easter=str2time("$year-$monEaster-$mdayEaster");

my $christmas = str2time("$year-12-25");
my ( $secC, $minC, $hourC, $mdayC, $monC, $yearC, $wdayC, $ydayC, $isdstC ) = localtime(str2time("$year-12-25"));
$wdayC = $wdayC ? $wdayC : 7;
my $adventBegin = $christmas - ($wdayC+21)*86400;

my @s=split ('\n',$_season);

foreach (@s) {
   next if ($_ eq "");
  ($date,$token)=split (',\s*',$_);
  ($from,$to)=split (' ',$date);
  if ($from =~ /E((\+|\-)\d+)/) {
    my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime ($easter + $1*86400);   
    $from=sprintf("%02d-%02d",$mon+1,$mday);
  } elsif ($from =~ /A((\+|\-)\d+)/) {
    my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime ($adventBegin + $1*86400);   
    $from=sprintf("%02d-%02d",$mon+1,$mday);
  }

  if (defined $to) {
    if ($to =~ /E((\+|\-)\d+)/) {
      my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime ($easter + $1*86400);   
      $to=sprintf("%02d-%02d",$mon+1,$mday);
    } elsif ($to =~ /A((\+|\-)\d+)/) {
      my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime ($adventBegin + $1*86400);   
      $to=sprintf("%02d-%02d",$mon+1,$mday);
    }
  }
  if (!defined ($to) and $from eq $md or (defined ($to) and $md ge $from and $md le $to)) {
    return($token);
  }
}
return ("none");
}
}



Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Jamo

Hallo Damian,
Ich bekomme eine Fehlermeldung:Undefined subroutine &main::str2time
In meiner 99_MyUtils.pm habe ich "use Time::Local;" definiert
Was muss ich da machen? Danke!
Bullseye auf iNUC, Homematic + HMIP(UART/HMUSB), Debmatic, HUEBridge, Zigbee/ConbeeII, FB, Alexa (fhem-lazy), Livetracking, LaCrosse JeeLink, LoRaWan / TTN / Chirpstack

Damian

Bei mir brauche ich str2time nicht zu definieren.

Dann trage bei dir ein:

...
sub myseason {
use Date::Parse qw(str2time);
my ($year,$md)=@_;
...
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Jamo

Bullseye auf iNUC, Homematic + HMIP(UART/HMUSB), Debmatic, HUEBridge, Zigbee/ConbeeII, FB, Alexa (fhem-lazy), Livetracking, LaCrosse JeeLink, LoRaWan / TTN / Chirpstack

Loredo

Diese vereinfachte Logik ist jetzt in ein eigenes Modul namens DaySchedule mit eingeflossen:
https://forum.fhem.de/index.php/topic,101942.0.html
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

TomLee

Musste während der Vorstellung im Webinar gleich an dieses DOIF denken. Danke. Werd ich mich wohl oder Übel mit befassen (müssen).