Geburtstagsliste für Statusdisplay

Begonnen von cetri, 14 August 2026, 12:33:19

Vorheriges Thema - Nächstes Thema

cetri

Da meine Kinder dauernd fragen wie lange es noch dauert bis Weihnachten ist oder bis sie Geburtstag haben, habe ich mit freundlicher KI-Hilfe ein AT erstellt das die Tage bis zu einem Ereignis und bei Geburtstagen das aktuelle Alter berechnet. Die Ergebnisse werden dann als Readings in ein beliebiges Device geschrieben. Zusätzlich werden die kommenden 2 Termine als Reading kommt1 und kommt2 geschrieben.

Bei mir werden dann die nächsten 2 Termine direkt im Homescreen des Statusdisplays angezeigt und die komplette Terminliste auf einer Unterseite.

Vielleicht ist da ja was für den Einen oder Anderen.

defmod at_Terminliste at *00:01:00 {\
  use Time::Piece;;\
  my $heute = Time::Piece->strptime(localtime->strftime("%Y-%m-%d"), "%Y-%m-%d");;\
  \
  # Terminliste Format: "Name"  => ["yyyy-mm-tt", 'Text der angezeigt werden soll wenn der Termin in der Zukunft liegt', 'Text der angezeigt werden soll wenn der Termin am aktuellen Tag ist']\
  # Nutzbare Variablen: $tage = Anzahl der Tage bis zum Termin, $alter = Alter für Geburtstage\
  my %geburtstage = (\
    "Sofia"  => ["2017-08-23", 'Noch $tage Tage, dann wird Sofia $alter Jahre alt', 'Sofia wird heute $alter Jahre alt! Alles Gute!'],\
    "Monja"  => ["1992-07-05", 'Noch $tage Tage bis Monjas $alter. Geburtstag',      'Monja feiert heute ihren $alter. Geburtstag!'],\
    "Joerg"  => ["1973-01-31", 'Noch $tage Tage bis zu Jörgs $alter. Ehrentag',    'Alles Gute zum $alter. Geburtstag, Jörg!'],\
    "Mia"    => ["2017-01-29", 'Noch $tage Tage bis zu Mias $alter. Geburtstag',    'Alles Gute zum $alter. Geburtstag, Mia!'],\
    "OmaUte" => ["1948-12-15", 'Noch $tage Tage bis zu Oma Utes $alter. Geburtstag', 'Alles Gute zum $alter. Geburtstag, Oma Ute!'],\
    "Ben"    => ["2021-09-07", 'Noch $tage Tage bis zu Bens $alter. Geburtstag',    'Alles Gute zum $alter. Geburtstag, Ben!'],\
"Heiligabend"    => ["2021-12-24", 'Noch $tage Tage bis zu Heiligabend',    'Heute ist Heiligabend. Der Weihnachtsmann kommt.'],\
  );;\
\
  my $device = "at_Terminliste";; # Device in dem die Readings gespeichert werden sollen. Entweder direkt im at oder in einem separaten Dummy\
  my @liste = ();; # Sammelliste für spätere Sortierung\
\
  while (my ($reading, $data) = each %geburtstage) {\
    my ($geburtsdatum_str, $txt_countdown, $txt_geburtstag) = @{$data};;\
\
    my $geburts_jahr  = substr($geburtsdatum_str, 0, 4);;\
    my $tag_monat     = substr($geburtsdatum_str, 5, 5);;\
\
    my $jahr = $heute->year;;\
    my $ziel = Time::Piece->strptime("$jahr-$tag_monat", "%Y-%m-%d");;\
    $ziel = Time::Piece->strptime(($jahr + 1) . "-$tag_monat", "%Y-%m-%d") if ($heute > $ziel);;\
\
    my $tage  = int(($ziel->epoch - $heute->epoch) / 86400);;\
    my $alter = $ziel->year - $geburts_jahr;;\
\
    my $text = ($tage == 0) ? $txt_geburtstag : $txt_countdown;;\
    $text =~ s/\$tage/$tage/g;;\
    $text =~ s/\$alter/$alter/g;;\
\
    # Einzelnes Reading für die jeweilige Person/Termin setzen\
    fhem("setreading $device $reading $text");;\
\
    # Ereignis mit Tage-Wert in Array speichern\
    push @liste, { tage => $tage, text => $text };;\
  }\
\
  # Liste nach verbleibenden Tagen aufsteigend sortieren\
  @liste = sort { $a->{tage} <=> $b->{tage} } @liste;;\
\
  # Die beiden nächsten Texte holen (falls mindestens 2 Einträge existieren)\
  my $kommt1 = $liste[0] ? $liste[0]->{text} : "";;\
  my $kommt2 = $liste[1] ? $liste[1]->{text} : "";;\
\
  # Die beiden neuen Readings setzen\
  fhem("setreading $device kommt1 $kommt1") if ($kommt1 ne "");;\
  fhem("setreading $device kommt2 $kommt2") if ($kommt2 ne "");;\
}

LG Jörg