Calendar, CalView & Co

Begonnen von TubeHead, 07 Februar 2026, 14:40:02

Vorheriges Thema - Nächstes Thema

TubeHead

#15
... so kann man es natürlich auch machen 8)

Ich habe es jetzt anders gelöst.
Ursprünglich wollte ich ja einen der Indikatoren abwechselnd in den entsprechenden Farben abwechselnd blinken lassen. Das kann AWTRIX aber nativ nicht. Blinken ja, aber nicht im Wechsel mit zwei oder drei Farben. Das hätte per MQTT in einer Schleife an alle drei Pixeluhren gesendet werden müssen; zu viel Aufwand und Payload...
Ich setze daher nun eine CustomApp mit den entsprechenden Farben.

Das Modul "Abfall" nutze ich nicht. Ich bin den manuellen Weg gegangen mit zwei DOIF:

defmod set_trash DOIF ([13:00] and defined fhem('get calendar events filter:field(summary)=~"Restmüll" limit:when=tomorrow')) (set $SELF bk 1)\
DOELSEIF ([13:00] and defined fhem('get calendar events filter:field(summary)=~"Gelbe" limit:when=tomorrow')) (set $SELF ye 1)\
DOELSEIF ([13:00] and defined fhem('get calendar events filter:field(summary)=~"Papier" limit:when=tomorrow')) (set $SELF bl 1)\
DOELSE (set $SELF bk 0, set $SELF ye 0, set $SELF bl 0)
attr set_trash do always
attr set_trash group Kalender
attr set_trash readingList bk ye bl
attr set_trash room 980 - Umwelt
attr set_trash stateFormat bk,ye,bl

setstate set_trash 0,0,0
setstate set_trash 2026-02-08 11:34:44 bk 0
setstate set_trash 2026-02-08 11:34:44 bl 0
setstate set_trash 2026-02-08 11:34:44 cmd 4
setstate set_trash 2026-02-08 11:34:44 cmd_event set_trash
setstate set_trash 2026-02-08 11:34:44 cmd_nr 4
setstate set_trash 2026-02-08 11:23:19 mode enabled
setstate set_trash 2026-02-08 11:34:44 state cmd_4
setstate set_trash 2026-02-08 11:23:19 timer_01_c01 08.02.2026 13:00:00
setstate set_trash 2026-02-08 11:23:19 timer_02_c02 08.02.2026 13:00:00
setstate set_trash 2026-02-08 11:23:19 timer_03_c03 08.02.2026 13:00:00
setstate set_trash 2026-02-08 11:34:44 ye 0

... und ...

defmod set_pixel_muell DOIF ([set_trash] eq "0,0,0") (set MQTT publish pixel1/custom/trash {} )\
DOELSEIF ([set_trash] eq "1,0,0") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [4, 0, 24, 8, "#BEBEBE"]},{"dt": [4, 1, "M ü l l", "#00FF00"]}]} )\
DOELSEIF ([set_trash] eq "0,1,0") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [4, 0, 24, 8, "#FFFF00"]},{"dt": [4, 1, "M ü l l", "#00FF00"]}]} )\
DOELSEIF ([set_trash] eq "0,0,1") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [4, 0, 24, 8, "#0000FF"]},{"dt": [4, 1, "M ü l l", "#00FF00"]}]} )\
DOELSEIF ([set_trash] eq "1,1,0") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [2, 0, 13, 8, "#FFFF00"]},{"df": [17, 0, 13, 8, "#BEBEBE"]},{"dt": [3, 1, "M ü  l l", "#101010"]}]} )\
DOELSEIF ([set_trash] eq "0,1,1") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [2, 0, 13, 8, "#FFFF00"]},{"df": [17, 0, 13, 8, "#0000FF"]},{"dt": [3, 1, "M ü  l l", "#ff33ff"]}]} )\
DOELSEIF ([set_trash] eq "1,0,1") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [2, 0, 13, 8, "#BEBEBE"]},{"df": [17, 0, 13, 8, "#0000FF"]},{"dt": [3, 1, "M ü  l l", "#000000"]}]} )\
DOELSEIF ([set_trash] eq "1,1,1") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [0, 0, 10, 8, "#FFFF00"]},{"df": [11, 0, 10, 8, "#BEBEBE"]},{"df": [22, 0, 10, 8, "#0000FF"]},{"dt": [4, 1, "M ü l l", "#00FF00"]}]} )
attr set_pixel_muell group Kalender
attr set_pixel_muell room 980 - Umwelt

setstate set_pixel_muell cmd_1
setstate set_pixel_muell 2026-02-08 11:34:44 Device set_trash
setstate set_pixel_muell 2026-02-08 11:21:15 cmd 1
setstate set_pixel_muell 2026-02-08 11:21:15 cmd_event set_pixel_muell
setstate set_pixel_muell 2026-02-08 11:21:15 cmd_nr 1
setstate set_pixel_muell 2026-02-08 11:34:44 e_set_trash_STATE 0,0,0
setstate set_pixel_muell 2026-02-08 11:21:00 mode enabled
setstate set_pixel_muell 2026-02-08 11:21:15 state cmd_1

Inzwischen habe ich auch die Daten vom Google-Kalender anstelle der lokalen Datei eingebunden. Nun warte ich auf 13:00 Uhr, um zu schauen, ob auch alles automatisch funktioniert ;)

EDIT:
Funktioniert nicht wie erwartet  >:(  Ich habe (mal wieder) übersehen, das ein DOIF beim ersten Treffer beendet wird. Ich muss also die Abfragen noch umstellen... Irgendwann lerne ich das auch noch mal  ::)

TubeHead

Ich komme hier nicht weiter  :-X

Das erste DOIF habe ich in drei einzelne zerlegt (set_trash1, set_trash2, set_trash3), jeweils für eine "Tonne". Die ReadingList ist nur in set_trash1 verblieben; die anderen setzen dort das Reading.
Das funktioniert soweit vollkommen schmerzfrei! Aber...

Um es zu testen, hatte ich die Triggerzeit knapp in die Zukunft bei allen verlegt. Nach dem Trigger aber haben alle drei (!) ausgelöst, was nicht mit dem Inhalt des Kalenders übereinstimmt. Morgen ist die graue und die gelbe Tonne dran, nicht aber die blaue. Dennoch wird auch die "gefunden".

Was übersehe ich hier?

defmod set_trash1 DOIF ([14:00] and defined fhem('get calendar events filter:field(summary)=~"Restmüll" limit:when=tomorrow')) (set $SELF bk 1)\
DOELSE (set $SELF bk 0)
attr set_trash1 group Kalender
attr set_trash1 readingList bk ye bl
attr set_trash1 room 980 - Umwelt
attr set_trash1 stateFormat bk,ye,bl

setstate set_trash1 1,1,1
setstate set_trash1 2026-02-08 14:00:00 bk 1
setstate set_trash1 2026-02-08 14:00:00 bl 1
setstate set_trash1 2026-02-08 14:00:00 cmd 1
setstate set_trash1 2026-02-08 14:00:00 cmd_event timer_1
setstate set_trash1 2026-02-08 14:00:00 cmd_nr 1
setstate set_trash1 2026-02-08 13:29:55 mode enabled
setstate set_trash1 2026-02-08 14:00:00 state cmd_1
setstate set_trash1 2026-02-08 14:30:52 timer_01_c01 09.02.2026 14:00:00
setstate set_trash1 2026-02-08 14:00:00 ye 1

defmod set_trash2 DOIF ([14:00] and defined fhem('get calendar events filter:field(summary)=~"Gelbe" limit:when=tomorrow')) (set set_trash1 ye 1)\
DOELSE (set set_trash1 ye 0)
attr set_trash2 group Kalender
attr set_trash2 room 980 - Umwelt

setstate set_trash2 cmd_1
setstate set_trash2 2026-02-08 14:00:00 cmd 1
setstate set_trash2 2026-02-08 14:00:00 cmd_event timer_1
setstate set_trash2 2026-02-08 14:00:00 cmd_nr 1
setstate set_trash2 2026-02-08 13:19:14 mode enabled
setstate set_trash2 2026-02-08 14:00:00 state cmd_1
setstate set_trash2 2026-02-08 14:30:52 timer_01_c01 09.02.2026 14:00:00

defmod set_trash3 DOIF ([14:00] and defined fhem('get calendar events filter:field(summary)=~"Papier" limit:when=tomorrow')) (set set_trash1 bl 1)\
DOELSE (set set_trash1 bl 0)
attr set_trash3 group Kalender
attr set_trash3 room 980 - Umwelt

setstate set_trash3 cmd_1
setstate set_trash3 2026-02-08 14:00:00 cmd 1
setstate set_trash3 2026-02-08 14:00:00 cmd_event timer_1
setstate set_trash3 2026-02-08 14:00:00 cmd_nr 1
setstate set_trash3 2026-02-08 13:19:01 mode enabled
setstate set_trash3 2026-02-08 14:00:00 state cmd_1
setstate set_trash3 2026-02-08 14:30:52 timer_01_c01 09.02.2026 14:00:00

TomLee

Hallo,

vermute der Mischmasch aus DOIF Syntax und Perl Syntax geht so nicht im DOIF-Modus.

Versuchs mal im Perl-Modus:

defmod set_trash3 DOIF { if ([14:00] and defined fhem('get calendar events filter:field(summary)=~"Papier" limit:when=tomorrow')) {fhem('set set_trash1 bl 1')}\
else  {fhem('set set_trash1 bl 0')}}

Gruß Thomas


TubeHead

Ich war natürlich nicht faul und habe noch einen anderen Weg versucht. Ich habe jetzt die Daten indirekt über CalView abgefragt, Das kann ich direkt aus DOIF machen. Damit habe ich mir halt drei DOIF's zusammengebaut für die drei möglichen Tonnen und dann damit das quasi-binär Dingens gesetzt, was ich für das Setzen der Pixel abfrage.
Das funktioniert so...

Den direkten Perl-Mode werde ich mal ausprobieren, obwohl ich, wenn's um PERL-Modus geht, in einem Jahr nicht mehr weiß, was das bedeutet... :-[  ???


Otto123

#19
Nur so als Tipp: ich finde für mich CalView (und jedes weitere Modul wie Abfall oder so) völlig entbehrlich und deine Lösung mit einer Menge an DOIFs klingt ziemlich kompliziert. Das Calendar Device selbst kann viel mehr als nur den Kalender importieren. Es hat halt kaum Readings die etwas "zeigen", trotzdem ist alles "drin"!
Ich habe mit zwei userReadings alles in einem Device gemacht, zeigt mir den Typ und die Tage bis zur nächsten Tonne. Die beiden Werte bringe ich zur Ansage/Anzeige.
Beispiel:
Diese Attribute erzeugt beim einlesen des Kalenders für jeden Alarm einen Alarm Trigger einen halben Tag davor
onCreateEvent { $e->{alarm}= $e->{start}-43200 }Bedeutet: ein zusätzlicher nextWakeup um 12:00 Uhr und einen Alarmtrigger da meine Tagestermine um 00:00 starten. Könntest Du auch auf 14:00 Uhr setzen und mit einem notify auf diesen Alarm triggern und deine Tonne ausgeben.
Dieses userReadings zeigt einfach die nächste Tonne als Reading an. Den Wert kann man mit ReadingsVal() oder mit set magic auslesen.
Tonne:triggered {fhem('get '.$name.' events format:custom="$S" limit:from=43200,count=1',1)}
Die Events die beim Alarm erzeugt werden sehen z.B. so aus:
2026-01-27_12:00:00 AbfallKalender changed: 5k7aqih1paafpfalafi5l5c28kgooglecom alarm
2026-01-27_12:00:00 AbfallKalender alarm: 5k7aqih1paafpfalafi5l5c28kgooglecom

Ich hatte zu so etwas ähnlichem mal eine ausführliche Notiz geschrieben.
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle

aktives Mitglied des FHEM e.V. (Technik)

TomLee

#20
Geht es nicht darum den Status von mehreren, möglichen Tonnen an einem Tag darzustellen?
Dein Vorschlag begrenzt es auf den nächsten Termin...

Otto123

wenns das gibt?
Seine DOIFs sehen mMn anders aus. Aber kann sein ich verstehe es falsch.
Egal, ich wollte ja zeigen, dass man nicht einen Sack voll andere Module braucht, bloß weil der Inhalt von Calendar nicht gleich "ins Auge fällt" ;)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle

aktives Mitglied des FHEM e.V. (Technik)

TubeHead

#22
... Ihr habt beide etwas stimmiges geäußert ...

@Otto123
Wenn es auf PERL-Ebene geht, bin ich faktisch raus. Da verstehe ich so gut wie nichts von. Von daher bin ich auch noch nicht dahinter gestiegen, was genau Du da machst...

@TomLee
Genau. Ziel ist es ja, eine CustomApp auf die Ulanzi zu schieben, passend zu den anstehenden Tonnen am Folgetag. Das heißt auch, ich muss im Vorfeld erstmal erfassen, ob alle drei Tonnen dran sind (eher selten), eine oder zwei, wobei dann zu schauen ist, welche genau.
Es erschien mir am einfachsten, hier quasi mit einem 3-Bit-Code zu arbeiten und jedem Bit eine Tonne zuzuordnen; ist zwar nicht wirklich ein Bit, sondern ein String, aber das spielt ja keine Rolle.

Letztlich habe ich aktuell das hier (ohne den SetState-Teil und Attribute; da stehen sowieso nur Raum und Gruppe drin):

Für die gelbe Tomme:
defmod set_trash_ye DOIF (([KalView:t_001_daysleftLong] eq "morgen" or [KalView:t_001_daysleftLong] eq "heute") and [KalView:t_001_summary] eq "Gelbe Tonne") (set set_pixel_muell ye 1)\
DOELSEIF (([KalView:t_002_daysleftLong] eq "morgen" or [KalView:t_002_daysleftLong] eq "heute") and [KalView:t_002_summary] eq "Gelbe Tonne") (set set_pixel_muell ye 1)\
DOELSEIF (([KalView:t_003_daysleftLong] eq "morgen" or [KalView:t_003_daysleftLong] eq "heute") and [KalView:t_003_summary] eq "Gelbe Tonne") (set set_pixel_muell ye 1)\
DOELSE (set set_pixel_muell ye 0)

Für die blaue Tonne:
defmod set_trash_bl DOIF (([KalView:t_001_daysleftLong] eq "morgen" or [KalView:t_001_daysleftLong] eq "heute") and [KalView:t_001_summary] eq "Papier") (set set_pixel_muell bl 1)\
DOELSEIF (([KalView:t_002_daysleftLong] eq "morgen" or [KalView:t_002_daysleftLong] eq "heute") and [KalView:t_002_summary] eq "Papier") (set set_pixel_muell bl 1)\
DOELSEIF (([KalView:t_003_daysleftLong] eq "morgen" or [KalView:t_003_daysleftLong] eq "heute") and [KalView:t_003_summary] eq "Papier") (set set_pixel_muell bl 1)\
DOELSE (set set_pixel_muell bl 0)

Für die schwarze Tonne:
defmod set_trash_bk DOIF (([KalView:t_001_daysleftLong] eq "morgen" or [KalView:t_001_daysleftLong] eq "heute") and [KalView:t_001_summary] eq "Restmüll") (set set_pixel_muell bk 1)\
DOELSEIF (([KalView:t_002_daysleftLong] eq "morgen" or [KalView:t_002_daysleftLong] eq "heute") and [KalView:t_002_summary] eq "Restmüll") (set set_pixel_muell bk 1)\
DOELSEIF (([KalView:t_003_daysleftLong] eq "morgen" or [KalView:t_003_daysleftLong] eq "heute") and [KalView:t_003_summary] eq "Restmüll") (set set_pixel_muell bk 1)\
DOELSE (set set_pixel_muell bk 0)

Somit habe ich in den Variablen der gererierten redingList im "set_pixel_muell" DOIF im state eine Kommagetrennte Kombination aus 0 und 1, welche ich dann dazu benutze, im selbigen DOIF die CustomApp für die Ulanzi zusammenzubauen:
defmod set_pixel_muell DOIF ([$SELF] eq "0,0,0") (set MQTT publish pixel1/custom/trash {} )\
DOELSEIF ([$SELF] eq "1,0,0") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [4, 0, 24, 8, "#525252"]},{"dt": [5, 1, "M ü l l", "#00FF00"]}]} )\
DOELSEIF ([$SELF] eq "0,1,0") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [4, 0, 24, 8, "#FFFF00"]},{"dt": [5, 1, "M ü l l", "#00FF00"]}]} )\
DOELSEIF ([$SELF] eq "0,0,1") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [4, 0, 24, 8, "#0000FF"]},{"dt": [5, 1, "M ü l l", "#00FF00"]}]} )\
DOELSEIF ([$SELF] eq "1,1,0") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [2, 0, 13, 8, "#FFFF00"]},{"df": [17, 0, 13, 8, "#525252"]},{"dt": [3, 1, "M ü", "#101010"]},{"dt": [19, 1, "l l", "#101010"]}]} )\
DOELSEIF ([$SELF] eq "0,1,1") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [2, 0, 13, 8, "#FFFF00"]},{"df": [17, 0, 13, 8, "#0000FF"]},{"dt": [3, 1, "M ü", "#ff33ff"]},{"dt": [19, 1, "l l", "#ff33ff"]}]} )\
DOELSEIF ([$SELF] eq "1,0,1") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [2, 0, 13, 8, "#525252"]},{"df": [17, 0, 13, 8, "#0000FF"]},{"dt": [3, 1, "M ü", "#000000"]},{"dt": [19, 1, "l l", "#000000"]}]} )\
DOELSEIF ([$SELF] eq "1,1,1") (set MQTT publish pixel1/custom/trash {"draw":[{"df": [0, 0, 10, 8, "#FFFF00"]},{"df": [11, 0, 10, 8, "#525252"]},{"df": [22, 0, 10, 8, "#0000FF"]},{"dt": [4, 1, "M ü l l", "#00FF00"]}]} )
attr set_pixel_muell readingList bk ye bl
attr set_pixel_muell stateFormat bk,ye,bl


Schön wäre es, wenn es im DOIF o.ä. eine Möglichkeit gäbe, eine tabellarische Zuweisung zu generieren, wie es z.B. in Basic mit "Select Case" möglich ist, oder ein 2D-Array... Sowas in der Art... Aber so geht's auch...

Anbei ein PNG-Download aus der Ulanzi mit aktuellem Status der CustomApp. Wenn es nur eine Tonne ist, zieht sich die farbige Fläche halt von X2 bis X30, bei drei Tonnen sind es halt drei Quadrate. Kann man auch von Weitem gut erkennen...