Systemvariablen für ical Termine setzen (am Beispiel ics eines Google Kalenders) für Mülltermine und Urlaub

Problemlösungen und Hinweise von allgemeinem Interesse zur Haussteuerung mit HomeMatic

Moderator: Co-Administratoren

Xel66
Beiträge: 14169
Registriert: 08.05.2013, 23:33
System: Alternative CCU (auf Basis OCCU)
Wohnort: Nordwürttemberg
Hat sich bedankt: 587 Mal
Danksagung erhalten: 1501 Mal

Systemvariablen für ical Termine setzen (am Beispiel ics eines Google Kalenders) für Mülltermine und Urlaub

Beitrag von Xel66 » 03.11.2023, 16:20

Hallo Forum,

ich werte schon seit Jahren meinen Google-Kalender zum Setzen bestimmter Systemvariablen (Urlaub, Abwesenheit) aus. Hierfür läuft auf Google-Servern ein Makro, welches ich selbst per URL abfragen kann. Diese Lösung wurde hier schon mal vor Jahren veröffentlicht. Grundsätzlich läuft das immer noch, aber trotzdem habe ich mir mal inspiriert durch diese Umsetzung eine eigene Lösung zusammengestrickt, die lokal auf der CCU läuft und den freigegebenen Kalender direkt ohne Google-Makro ausliest und entsprechende Sytemvariablen auf der CCU setzt, die ich weiter in Programmen verwenden kann.

Vorteil der Nutzung eines Online-Kalenders ist, dass man diesen ganz einfach per Smartphone, Tablet oder Rechner pflegen und auch für andere Zwecke (z.B. Terminerinnerungen) verwenden kann. Auch eine Einbindung in eine Visualisierung ist recht einfach parallel machbar. Wie Kalender freigeben werden, ist relativ einfach zu finden. Daher lasse ich diese Beschreibung hier weg. Ich empfehle für solche Dinge einen zusätzlichen anonymen Kalender zu führen, in dem nicht gerade private Termine vorgehalten werden. Das hält die Lösung schlank und den Scriptlauf schnell. Auf meiner CCU/RM auf RaspberryPi3-Basis läuft das Script in unter 0,5 Sekunden. Außderem ist es dem Schutz privater Daten dienlich, wenn mal die Abfrage-URL durch irgendetwas (z.B. Supportanfrage - Beispiele mit persönlichen Daten habe ich hier im Forum schon öfter gesehen) unbeabsichtigt geleakt wird.

Das Script liest die .ics-Datei aus und speichert sie in einer Scriptvariable, anschließend wird er erste Identifier eines Termineintrages gesucht und danach startet die Auswertung auf die Suchworte "Urlaub" und "Abwesend". Ich werte diese Status unterschiedlich aus. "Urlaub" bedeutet, dass ich zu Hause bin und "Abwesend" bedarf keiner Erklärung. Mit diesen Status kann ich u.a. Einfluss auf die Heizungssteuerung nehmen. Diese Suchworte werden in den Daten des aktuellen und des Folgetages gesucht und die Ergebnisse in Merkervariablen (z.B. "urlaub_m") zwischengespeichert. Am Ende des Scripts werden die Sytemvariablen analog zum Status der zwischengespeicherten Status gesetzt. Ich habe beide Möglichkeiten zur Abfrage (CUxD und system.Exec) implementiert. Die jeweilige Abfrageart kann durch das Entfernen und Setzen der Kommentarausrufezeichen de-/aktiviert werden.

Die hier vorgestellte Lösung benötigt nur täglich einen Scriptlauf nach dem Datumswechsel. Die Termine im Kalender müssen zwingend als Ganztagestermine gesetzt sein. Auch mehrere Tage (ohne explizite Uhrzeiten) sind möglich. Ich plane nicht, die Abfrage um Uhrzeiten zu erweitern, denn zur zeitnahen Auswertung müsste dieses Script zyklisch laufen. Dieses häufige externe Kommunikation möchte ich unbedingt vermeiden und ist für den geplanten Anwendungszweck auch nicht notwendig. Für die Auswertung und Verarbeitung in der CCU sind folgende boolsche Systemvariablen notwendig "Z_Urlaub", "Z_UrlaubMorgen", "Z_Abwesend" und "Z_AbwesendMorgen". Somit können die Status für den aktuellen und den Folgetag gesetzt werden. Die Namen können im unteren Teil des Scripts an die eigenen ggf. abweichenden Namen angepasst werden. Ich habe mich zur besseren Nachvollziehbarkeit bemüht, die einzelnen Schritte im Script selbst zu dokumentieren.

Hier nun das Script:

Code: Alles auswählen

! ##### Abfrage eines Online-Kalenders und Setzen von Systemvariablen ######
! Stand 03.11.2023 Quelle: https://homematic-forum.de/forum/viewtopic.php?f=31&t=80441#p783128
! ----------------------------------------------------------
! Es ist möglich, eigene Google-Kalender freizugeben und auch von extern einzulesen.
! Die URL zum eigenen freigegebenen Kalender kann unter "url=..." angepasst werden.
! Dieser Kalender kann sowohl vom Smartphone als auch per Rechner gepflegt werden.
! Somit ist eine Online-Datenpflege relativ einfach.

! Funktion:
! - Das Script liest die .ics Datei aus
! - holt sich das Systemdatum
! - ermittelt einen auf das Systemdatum passenden Eintrag
! - vergleicht Einträge mit dem Suchstings (Urlaub/Abwesend)
! - setzt Systemvariablen entsprechen der Suchworte
! Das Script enthält die Möglichkeit der Abfrage per system.Exec und per CUxD-Gerät.
! Für die Alternative Abfrage die Ausrufezeichen zwichen "Abfrage per..." und "Ende Abfrage"-Zeile entfernen und bei der anderen Variante setzen.
! Für die Auswertung in der CCU sind folgende boolsche Systemvariablen notwendig "Z_Urlaub", "Z_UrlaubMorgen", "Z_Abwesend" und "Z_AbwesendMorgen".
! Werden eigene Namen verwendet, sind diese im letzten Teil des Scripts anzupassen.
! -----------------------------------------------------------


! +++++ Definition der verwendeten Scritptvariablen +++++
! bei Verwendung anderer Quelldaten als Google-Kalender die ...ID-Variablen anpassen, abweichende Bezeichnungen werden durch .Length() im Script berücksichtigt
string startID = "DTSTART;VALUE=DATE:";                      ! Identifier für das Startdatum
string endID = "DTEND;VALUE=DATE:";                          ! Identifier für das Enddatum
string beginEventID = "BEGIN:VEVENT";                        ! Identifier für Termineintragsbeginn
string endeEventID = "END:VEVENT";                           ! Identifier für Termineintragsende
var url = "https://calendar.google.com/calendar/ical/googleigenegheimekennung%40group.calendar.google.com/private-hiermuessenauchdieeigenendatenrein/basic.ics";

! Ab hier nichts mehr ändern
integer laenge ;
integer vevent_start;
integer vevent_ende;
string vevent_single;
integer vevent_dtstart;
integer vevent_dtend;
boolean urlaub_m;
boolean urlaubf_m;
boolean abwesend_m;
boolean abwesendf_m;

! +++++ Abfrage der Datei mit CUxD und Einlesen in Variable / Dateilänge in Variable +++++
! Abfrage per CUxD-Gerät
! dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("timeout 10 wget --timeout=10 --no-check-certificate -q -O - '"#url#"'");
! dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
! string ics_quelldaten = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
! Ende Anfrage per CUxD



! +++++ Abfrage per system.Exec() +++++
string stdout; string stderr;
system.Exec("timeout 10 wget --timeout=10 -q -O - '"#url#"'", &stdout, &stderr);
if (stderr <> "") { quit; }                                  ! Scriptabbruch, wenn Kalenderabfrage einen Fehler gemeldet hat
string ics_quelldaten = stdout;
! Ende Abfrage per system.Exec()

laenge = ics_quelldaten.Length();
if (laenge < 1) { WriteLine("Keine Quelldaten vorhanden, Verarbeitung beendet."); quit; }

! +++++ Lokalzeit einlesen, und 90000 (nicht 86400) Sekunden zur Berücksichtigung der Sommerzeit für das Enddatum aufaddieren +++++
integer datum_a = localtime.Format("%Y%m%d").ToInteger();         ! aktuelles Datum als Startwert
integer datum_e = (localtime+90000).Format("%Y%m%d").ToInteger(); ! Datum des Terminende und Start des Folgetages
integer datum_f = (localtime+176400).Format("%Y%m%d").ToInteger();! Datum des Terminende des Folgetages

vevent_start = ics_quelldaten.Find(beginEventID);                ! Suche des ersten Event-Beginn-Ifentifiers
while (vevent_start > 0) {
vevent_ende = ics_quelldaten.Find(endeEventID);                  ! Suche des ersten Event-Ende-Identifiers
vevent_single = ics_quelldaten.Substr(vevent_start,((endeEventID.Length())+vevent_ende-vevent_start)); ! Kürzung auf Einzeltermineintrag
vevent_dtstart = vevent_single.Substr((startID.Length())+(vevent_single.Find(startID)),8).ToInteger();! Auslesen des Startdatums des Termins
vevent_dtend = vevent_single.Substr((endID.Length())+(vevent_single.Find(endID)),8).ToInteger();      ! Auslesen des Enddatum des Termins
if ((datum_a >= vevent_dtstart) && (datum_e <= vevent_dtend)) {   ! Prüfung ob aktuelles Datum zwischen Terminanfang und -ende liegt
      integer urlaub = vevent_single.Find("SUMMARY:Urlaub");      ! Suche nach "Urlaub" und Setzen des Status
      if ((urlaub > 0) && (urlaub < vevent_ende)){
           urlaub_m = true;
           if ((urlaub > 0) && (datum_e < vevent_dtend)) { urlaubf_m = true;}! Berücksichtigung Mehrtagestermin
           }
      integer abwesend = vevent_single.Find("SUMMARY:Abwesend");   ! Suche nach "Abwesend" und Setzen des Status
      if ((abwesend > 0) && (abwesend < vevent_ende)) {
            abwesend_m = true;
            if ((abwesend > 0) && (datum_e < vevent_dtend)) { abwesend_m = true;} ! Berücksichtigung Mehrtagestermin
           }
      ics_quelldaten = ics_quelldaten.Substr((endeEventID.Length())+vevent_ende, (endeEventID.Length())-laenge - vevent_ende); ! Kürzen der Quelldatei
      laenge = ics_quelldaten.Length();
      vevent_start = ics_quelldaten.Find(beginEventID);
}    
elseif ((datum_e >= vevent_dtstart) && (datum_f <= vevent_dtend)) {! Prüfung ob Datum des Folgetags zwischen Terminanfang und -ende liegt
      integer urlaub = vevent_single.Find("SUMMARY:Urlaub");       ! Suche nach "Urlaub" und Setzen des Status für den Folgetag
      if ((urlaub > 0) && (urlaub <= vevent_dtend)){
           urlaubf_m = true;}
      integer abwesend = vevent_single.Find("SUMMARY:Abwesend");   ! Suche nach "Abwesend" und Setzen des Status
      if ((abwesend > 0) && (abwesend <= vevent_dtend)) { abwesendf_m = true;}
      ics_quelldaten = ics_quelldaten.Substr((endeEventID.Length())+vevent_ende, (endeEventID.Length())-laenge - vevent_ende); ! Kürzen der Quelldatei
      laenge = ics_quelldaten.Length();
      vevent_start = ics_quelldaten.Find(beginEventID);
      }
else {ics_quelldaten = ics_quelldaten.Substr((endeEventID.Length())+vevent_ende, (endeEventID.Length())-laenge - vevent_ende);
! Kürzen der Quelldatei
      laenge = ics_quelldaten.Length();
      vevent_start = ics_quelldaten.Find(beginEventID);
      }
} ! Ende while


! +++++ Abfrage der zwischengespeicherten Status und Setzen der Systemvariablen
       if (urlaub_m > 0)  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Z_Urlaub").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Z_Urlaub").State("false");}
       if (urlaubf_m > 0)  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Z_UrlaubMorgen").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Z_UrlaubMorgen").State("false");}
       if (abwesend_m > 0) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Z_Abwesend").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Z_Abwesend").State("false");}
       if (abwesendf_m > 0) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Z_AbwesendMorgen").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Z_AbwesendMorgen").State("false");}


! +++++ Aufräumen
       ics_quelldaten = "";                                        ! Leeren der Scriptvariable
       vevent_single = "";                                         ! Leeren der Scriptvariable
! ===== ENDE =====
Vielleicht kann ja jemand etwas mit anfangen.

Gruß Xel66
-------------------------------------------------------------------------------------------
524 Kanäle in 146 Geräten und 267 CUxD-Kanäle in 34 CUxD-Geräten:
343 Programme, 334 Systemvariablen und 183 Direktverknüpfungen,
RaspberryMatic Version: 3.65.11.20221005 + Testsystem: CCU2 2.61.7
-------------------------------------------------------------------------------------------
Einsteigerthread, Programmlogik-Thread, WebUI-Handbuch

Xel66
Beiträge: 14169
Registriert: 08.05.2013, 23:33
System: Alternative CCU (auf Basis OCCU)
Wohnort: Nordwürttemberg
Hat sich bedankt: 587 Mal
Danksagung erhalten: 1501 Mal

Re: Systemvariablen für ical Termine setzen (am Beispiel ics eines Google Kalenders) für Mülltermine und Urlaub

Beitrag von Xel66 » 03.11.2023, 16:22

Hier noch eine einfachere Variante obigen Scripts für Einzeltermine am Beispiel eines Müllkalenders. Die Funktionsweise ist ähnlich. Es erfolgt ein mehrfacher Durchlauf mit dem Suchstring des aktuellen Datums, um auch mehrfache Termine abzudecken (bei uns wird im Sommer die Biotonne wöchentlich geleert ansonsten immer im Wechsel mit der Restmülltonne). Ich setze allerdings immer noch meine hier veröffentlichte Methode ein, aber das benutzte Tablet schwächelt langsam. Mit diesem Script habe ich ein Fallback. Mit den gesetzten Systemvariablen generiere ich morgens einen Ansagetext für die Wiedergabe über Smartspeaker als ultimative Aufforderung zum Rausstellen der Tonnen. Durch Verschieben der Terminabfrage (in den Zeilen integer "datum_a =" und "integer datum_e =" könnte man durch Addition eines Tages (86400 Sekunden) ein Setzen am Vortag ereichen und dann eine Einnerung am Abend zum Rausstellen generieren. Das Script benötigt die Systemvariablen "Muelltonne_schwarz", "Muelltonne_braun" und "Muelltonne_blau".

Hier nun das Script:

Code: Alles auswählen

! ##### Abfrage eines Online-Kalenders und Setzen von Systemvariablen ######
! Stand 03.11.2023 Quelle: https://homematic-forum.de/forum/viewtopic.php?f=31&t=80441#p783128
! ----------------------------------------------------------
! Erklärung:
! Es ist möglich, eigene Google-Kalender freizugeben und auch von extern einzulesen.
! Dieser Kalender kann sowohl vom Smartphone, Tablet als auch per Rechner gepflegt werden.
! Es ist auch möglich, vom Abfallentsorger zur Verfügung gestellte .ics-Dateien zu importieren.
! Somit ist eine Online-Datenpflege relativ einfach.
! Funktion:
! - Das Script liest die .ics Datei aus
! - holt sich das Systemdatum
! - sucht das aktuelle Datum in den Quelldaten und durchsucht die Einträge nach Müllsorten
! - setzt Systemvariablen in Abhängigkeit von gefundenen Übereinstimmungen
!
! Vorraussetzung:
! CuxD-Gerät CUxD.CUX2801001:1
! evtl. CuxD-Gerätenummer anpassen


! -----------------------------------------------------------


! +++++ Definition Variablen +++++

string startID = "DTSTART;VALUE=DATE:";                      ! Identifier für das Startdatum
string endID = "DTEND;VALUE=DATE:";                          ! Identifier für das Enddatum
integer laenge ;
var url = "https://calendar.google.com/calendar/ical/googleigenegheimekennung%40group.calendar.google.com/private-hiermuessenauchdieeigenendatenrein/basic.ics";

! +++++ Abfrage der Datei mit CUxD und Einlesen in Variable / Dateilänge in Variable +++++
! Abfrage per CUxD-Gerät
! dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("timeout 10 wget --timeout=10 --no-check-certificate -q -O - '"#url#"'");
! dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
! string ics_quelldaten = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
! Ende Anfrage per CUxD

! Abfrage über system.Exec()
string stdout; string stderr;
system.Exec("timeout 10 wget --timeout=10 -q -O - '"#url#"'", &stdout, &stderr);
if (stderr <> "") { quit; }                                       ! Scriptabbruch, wenn Kalenderabfrage einen Fehler gemeldet hat
string ics_quelldaten = stdout;
! Ende Abfrage über system.Exec()

integer laenge = ics_quelldaten.Length();

! +++++ Systemdatum einlesen, und 90000 Sekunden zur Berücksichtigung der Sommerzeitumstellung für das Enddatum aufaddieren +++++

integer datum_a = localtime.Format("%Y%m%d").ToInteger();         ! aktuelles Datum als Startwert
integer datum_e = (localtime+90000).Format("%Y%m%d").ToInteger(); ! Datum des Folgetages als Terminende

string sucheanfang = startID#datum_a;                             ! Zusammensetzung des Suchstrings für die Suche
string sucheende = endID#datum_e;                                 ! Zusammensetzung des Suchstings für die Suche (für mehrtägig Termine)
integer anfang = ics_quelldaten.Find(sucheanfang);                ! erste Fundstelle Terminbeginn
integer ende = ics_quelldaten.Find(sucheende);                    ! erste Fundstelle Terminende
while (anfang > 0) {                                              ! Mehrfachdurchlauf für mehrere Termine pro Tag
    ics_quelldaten = ics_quelldaten.Substr(anfang,(laenge - anfang));  ! Kürzung der Quelldatei bis zur ersten Fundstelle
    laenge = ics_quelldaten.Length();
    integer eventende = ics_quelldaten.Find("END:VEVENT");        ! Feststellen Ende des Termineintrages (zur Abgrenzung gegen Folgetermine)
    integer bio = ics_quelldaten.Find("SUMMARY:Bio");             ! Suche nach Müllart und Setzen des Status
        if ((bio > 0) && (bio < eventende)) { boolean bio_m = true;}
    integer rest = ics_quelldaten.Find("SUMMARY:Rest");           ! Suche nach Müllart und Setzen des Status
       if ((rest > 0) && (rest < eventende)) { boolean rest_m = true;}
    integer papier = ics_quelldaten.Find("SUMMARY:Papier");       ! Suche nach Müllart und Setzen des Status
        if ((papier > 0) && (papier < eventende)) { boolean papier_m = true;}
     ics_quelldaten = ics_quelldaten.Substr(eventende,(laenge - eventende)); ! Kürzung der Quelldatei um bereits gefundene Termine
     anfang = ics_quelldaten.Find(sucheanfang);                    ! Ende der while-Schleife und Rücksprung für nächsten Termin am gleichen Tag
}
!  ++++++ Abfrage der zwischengespeicherten Status und Setzen der Systemvariablen  ++++++
       if (bio_m > 0)  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Muelltonne_braun").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Muelltonne_braun").State("false");}
       if (rest_m > 0) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Muelltonne_schwarz").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Muelltonne_schwarz").State("false");}
       if (papier_m > 0) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Muelltonne_blau").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Muelltonne_blau").State("false");}
       ics_quelldaten = "";                                        ! Leeren der Scriptvariable
! ===== Programmende =====
Gruß Xel66
-------------------------------------------------------------------------------------------
524 Kanäle in 146 Geräten und 267 CUxD-Kanäle in 34 CUxD-Geräten:
343 Programme, 334 Systemvariablen und 183 Direktverknüpfungen,
RaspberryMatic Version: 3.65.11.20221005 + Testsystem: CCU2 2.61.7
-------------------------------------------------------------------------------------------
Einsteigerthread, Programmlogik-Thread, WebUI-Handbuch

Roli01
Beiträge: 102
Registriert: 06.04.2008, 23:56
Wohnort: nähe Krems/Donau
Danksagung erhalten: 3 Mal

Re: Systemvariablen für ical Termine setzen (am Beispiel ics eines Google Kalenders) für Mülltermine und Urlaub

Beitrag von Roli01 » 02.02.2024, 21:32

Hallo!

Könntest du mir bei deinem tollen Script bitte weiter helfen?
Ich bekomme es einfach nicht zum laufen.
Gooogle Kalender ist angelegt und freigegeben.
Systemvariablen sind erstellt.

Ich habe es versucht an unsere Kalendereinträge anzupassen. Die ics habe ich von unserem Anbieter importiert. Dieser hat im Kalender immer die Einträge "Abholung Bio" "Abholung Altpapier" "Abholung Gelber Sack" und "Abholung Restmuell"
Der macht aber leider keinen Ganztagestermin. Habe aber versuchsweise einen Ganztagestermin erstellt der aber auch nicht funkt.

Die Variablen die ich erstellt habe heißen:
Bio
Restmuell
Gelber Sack
Altpapier

Dies habe ich versucht in dein Script einzupflegen. Hoffe das passt so.
Dann noch die Google Kalender Adresse eingefügt und auf Cuxd Gerät geändert.

Muss ich in deinem Script noch etwas anpassen?

Vielen Dank
Roli

Code: Alles auswählen

! ##### Abfrage eines Online-Kalenders und Setzen von Systemvariablen ######
! Stand 03.11.2023 Quelle: https://homematic-forum.de/forum/viewtopic.php?f=31&t=80441#p783128
! ----------------------------------------------------------
! Erklärung:
! Es ist möglich, eigene Google-Kalender freizugeben und auch von extern einzulesen.
! Dieser Kalender kann sowohl vom Smartphone, Tablet als auch per Rechner gepflegt werden.
! Es ist auch möglich, vom Abfallentsorger zur Verfügung gestellte .ics-Dateien zu importieren.
! Somit ist eine Online-Datenpflege relativ einfach.
! Funktion:
! - Das Script liest die .ics Datei aus
! - holt sich das Systemdatum
! - sucht das aktuelle Datum in den Quelldaten und durchsucht die Einträge nach Müllsorten
! - setzt Systemvariablen in Abhängigkeit von gefundenen Übereinstimmungen
!
! Vorraussetzung:
! CuxD-Gerät CUxD.CUX2801001:1
! evtl. CuxD-Gerätenummer anpassen


! -----------------------------------------------------------


! +++++ Definition Variablen +++++

string startID = "DTSTART;VALUE=DATE:";                      ! Identifier für das Startdatum
string endID = "DTEND;VALUE=DATE:";                          ! Identifier für das Enddatum
integer laenge ;
var url = "https://calendar.google.com/calendar/ical/xxxxxxxxxxxxxxxxxxxxxxx%40group.calendar.google.com/public/basic.ics";

! +++++ Abfrage der Datei mit CUxD und Einlesen in Variable / Dateilänge in Variable +++++
! Abfrage per CUxD-Gerät
dom.GetObject("CUxD.CUX2801001:16.CMD_SETS").State("timeout 10 wget --timeout=10 --no-check-certificate -q -O - '"#url#"'");
dom.GetObject("CUxD.CUX2801001:16.CMD_QUERY_RET").State(1);
string ics_quelldaten = dom.GetObject("CUxD.CUX2801001:16.CMD_RETS").State();
! Ende Anfrage per CUxD

! Abfrage über system.Exec()
!string stdout; string stderr;
!system.Exec("timeout 10 wget --timeout=10 -q -O - '"#url#"'", &stdout, &stderr);
!if (stderr <> "") { quit; }                                       ! Scriptabbruch, wenn Kalenderabfrage einen Fehler gemeldet hat
!string ics_quelldaten = stdout;
! Ende Abfrage über system.Exec()

integer laenge = ics_quelldaten.Length();

! +++++ Systemdatum einlesen, und 90000 Sekunden zur Berücksichtigung der Sommerzeitumstellung für das Enddatum aufaddieren +++++

integer datum_a = localtime.Format("%Y%m%d").ToInteger();         ! aktuelles Datum als Startwert
integer datum_e = (localtime+90000).Format("%Y%m%d").ToInteger(); ! Datum des Folgetages als Terminende

string sucheanfang = startID#datum_a;                             ! Zusammensetzung des Suchstrings für die Suche
string sucheende = endID#datum_e;                                 ! Zusammensetzung des Suchstings für die Suche (für mehrtägig Termine)
integer anfang = ics_quelldaten.Find(sucheanfang);                ! erste Fundstelle Terminbeginn
integer ende = ics_quelldaten.Find(sucheende);                    ! erste Fundstelle Terminende
while (anfang > 0) {                                              ! Mehrfachdurchlauf für mehrere Termine pro Tag
    ics_quelldaten = ics_quelldaten.Substr(anfang,(laenge - anfang));  ! Kürzung der Quelldatei bis zur ersten Fundstelle
    laenge = ics_quelldaten.Length();
    integer eventende = ics_quelldaten.Find("END:VEVENT");        ! Feststellen Ende des Termineintrages (zur Abgrenzung gegen Folgetermine)
    integer bio = ics_quelldaten.Find("SUMMARY:Abholung Biotonne");             ! Suche nach Müllart und Setzen des Status
        if ((bio > 0) && (bio < eventende)) { boolean bio_m = true;}
    integer rest = ics_quelldaten.Find("SUMMARY:Abholung Restmuell");           ! Suche nach Müllart und Setzen des Status
       if ((rest > 0) && (rest < eventende)) { boolean rest_m = true;}
    integer gelber = ics_quelldaten.Find("SUMMARY:Abholung Gelber Sack");       ! Suche nach Müllart und Setzen des Status
        if ((gelber > 0) && (gelber < eventende)) { boolean gelber_m = true;}
    integer papier = ics_quelldaten.Find("SUMMARY:Abholung Altpapier");       ! Suche nach Müllart und Setzen des Status
        if ((papier > 0) && (papier < eventende)) { boolean papier_m = true;}
     ics_quelldaten = ics_quelldaten.Substr(eventende,(laenge - eventende)); ! Kürzung der Quelldatei um bereits gefundene Termine
     anfang = ics_quelldaten.Find(sucheanfang);                    ! Ende der while-Schleife und Rücksprung für nächsten Termin am gleichen Tag
}
!  ++++++ Abfrage der zwischengespeicherten Status und Setzen der Systemvariablen  ++++++
       if (bio_m > 0)  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Bio").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Bio").State("false");}
       if (rest_m > 0) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Restmuell").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Restmuell").State("false");}
       if (gelber_m > 0) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Gelber Sack").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Gelber Sack").State("false");}
       if (papier_m > 0) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Altpapier").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Altpapier").State("false");}
       ics_quelldaten = "";                                        ! Leeren der Scriptvariable
! ===== Programmende =====
492 Kanäle in 92 Geräten und 37 CUxD-Kanäle in 4 CUxD-Geräten:


Xel66
Beiträge: 14169
Registriert: 08.05.2013, 23:33
System: Alternative CCU (auf Basis OCCU)
Wohnort: Nordwürttemberg
Hat sich bedankt: 587 Mal
Danksagung erhalten: 1501 Mal

Re: Systemvariablen für ical Termine setzen (am Beispiel ics eines Google Kalenders) für Mülltermine und Urlaub

Beitrag von Xel66 » 03.02.2024, 10:16

Roli01 hat geschrieben:
02.02.2024, 21:32
Muss ich in deinem Script noch etwas anpassen?
FOA sieht Deine Abfrage-URL schon anders aus, als mein Beispiel oben (bei Dir steht "...public/basic.ics", bei mir ist hinter "steht dort ..."private-xxxx" mit einer langen Kennung). Kann auch an der Freigabeart liegen. Bekommst Du Daten, wenn Du diese URL in einem Browser verwendest? Wenn nicht, dann hakt es schon da (dann würde es auch nicht mit der Alternativlösung funktionieren). Ferner weiß ich nicht, ob der Aufruf "ics_quelldaten.Find" mit Leerzeichen im Suchstring zurechtkommt. Habe ich nie getestet, weil mein Kalender in den Eventbezeichnern keine Leerzeichen enthält. Ich meide beim Scriping in solchen Funktionen grundsätzlich Leer- und Sonderzeichen. Gibt nur Probleme. Ich will nicht für jede Kleinigkeit eine Fehlerbehandlungsroutine implementieren müssen.

In meinem Abfallkalender steht im Original vom Entsorger auch immer "...müll" hinter den Einträgen. Die habe ich vor dem Import nach Google einfach entfernt (Öffnen mit Editor und Suchen/Ersetzen mit nix). Das hat aber u.a. auch historische Gründe. Es läuft im Hintergrund und an einem anderen Standort noch eine andere/ältere Lösung von mir (Auslesen von Kalendereinträgen mit Tasker auf einem Tablet, welches dann auch Systemvariablen in der CCU setzen kann).

Gruß Xel66
-------------------------------------------------------------------------------------------
524 Kanäle in 146 Geräten und 267 CUxD-Kanäle in 34 CUxD-Geräten:
343 Programme, 334 Systemvariablen und 183 Direktverknüpfungen,
RaspberryMatic Version: 3.65.11.20221005 + Testsystem: CCU2 2.61.7
-------------------------------------------------------------------------------------------
Einsteigerthread, Programmlogik-Thread, WebUI-Handbuch

Roli01
Beiträge: 102
Registriert: 06.04.2008, 23:56
Wohnort: nähe Krems/Donau
Danksagung erhalten: 3 Mal

Re: Systemvariablen für ical Termine setzen (am Beispiel ics eines Google Kalenders) für Mülltermine und Urlaub

Beitrag von Roli01 » 04.02.2024, 15:58

Hi, danke für die Antworten.

Habs jetzt nochmals probiert und sicherheitshalber bei deinem script bis auf meinen Kalenderlink nichts geändert.
Die Systemvariablen habe ich auch von dir übernommen.
Dann einen Ganztagestermin in meinem Abfallkalender mit dem eintrag "Bio" angelegt und unter scrip testen ausgeführt.

Leider wird die Variable wieder nicht geändert.

Code: Alles auswählen

! ##### Abfrage eines Online-Kalenders und Setzen von Systemvariablen ######
! Stand 03.11.2023 Quelle: https://homematic-forum.de/forum/viewtopic.php?f=31&t=80441#p783128
! ----------------------------------------------------------
! Erklärung:
! Es ist möglich, eigene Google-Kalender freizugeben und auch von extern einzulesen.
! Dieser Kalender kann sowohl vom Smartphone, Tablet als auch per Rechner gepflegt werden.
! Es ist auch möglich, vom Abfallentsorger zur Verfügung gestellte .ics-Dateien zu importieren.
! Somit ist eine Online-Datenpflege relativ einfach.
! Funktion:
! - Das Script liest die .ics Datei aus
! - holt sich das Systemdatum
! - sucht das aktuelle Datum in den Quelldaten und durchsucht die Einträge nach Müllsorten
! - setzt Systemvariablen in Abhängigkeit von gefundenen Übereinstimmungen
!
! Vorraussetzung:
! CuxD-Gerät CUxD.CUX2801001:1
! evtl. CuxD-Gerätenummer anpassen


! -----------------------------------------------------------


! +++++ Definition Variablen +++++

string startID = "DTSTART;VALUE=DATE:";                      ! Identifier für das Startdatum
string endID = "DTEND;VALUE=DATE:";                          ! Identifier für das Enddatum
integer laenge ;
var url = "https://calendar.google.com/calendar/ical/xxxxxxxxxxxxxxxxxxxxx%40group.calendar.google.com/private-xxxxxxxxxxxxxx/basic.ics";

! +++++ Abfrage der Datei mit CUxD und Einlesen in Variable / Dateilänge in Variable +++++
! Abfrage per CUxD-Gerät
! dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("timeout 10 wget --timeout=10 --no-check-certificate -q -O - '"#url#"'");
! dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
! string ics_quelldaten = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
! Ende Anfrage per CUxD

! Abfrage über system.Exec()
string stdout; string stderr;
system.Exec("timeout 10 wget --timeout=10 -q -O - '"#url#"'", &stdout, &stderr);
if (stderr <> "") { quit; }                                       ! Scriptabbruch, wenn Kalenderabfrage einen Fehler gemeldet hat
string ics_quelldaten = stdout;
! Ende Abfrage über system.Exec()

integer laenge = ics_quelldaten.Length();

! +++++ Systemdatum einlesen, und 90000 Sekunden zur Berücksichtigung der Sommerzeitumstellung für das Enddatum aufaddieren +++++

integer datum_a = localtime.Format("%Y%m%d").ToInteger();         ! aktuelles Datum als Startwert
integer datum_e = (localtime+90000).Format("%Y%m%d").ToInteger(); ! Datum des Folgetages als Terminende

string sucheanfang = startID#datum_a;                             ! Zusammensetzung des Suchstrings für die Suche
string sucheende = endID#datum_e;                                 ! Zusammensetzung des Suchstings für die Suche (für mehrtägig Termine)
integer anfang = ics_quelldaten.Find(sucheanfang);                ! erste Fundstelle Terminbeginn
integer ende = ics_quelldaten.Find(sucheende);                    ! erste Fundstelle Terminende
while (anfang > 0) {                                              ! Mehrfachdurchlauf für mehrere Termine pro Tag
    ics_quelldaten = ics_quelldaten.Substr(anfang,(laenge - anfang));  ! Kürzung der Quelldatei bis zur ersten Fundstelle
    laenge = ics_quelldaten.Length();
    integer eventende = ics_quelldaten.Find("END:VEVENT");        ! Feststellen Ende des Termineintrages (zur Abgrenzung gegen Folgetermine)
    integer bio = ics_quelldaten.Find("SUMMARY:Bio");             ! Suche nach Müllart und Setzen des Status
        if ((bio > 0) && (bio < eventende)) { boolean bio_m = true;}
    integer rest = ics_quelldaten.Find("SUMMARY:Rest");           ! Suche nach Müllart und Setzen des Status
       if ((rest > 0) && (rest < eventende)) { boolean rest_m = true;}
    integer papier = ics_quelldaten.Find("SUMMARY:Papier");       ! Suche nach Müllart und Setzen des Status
        if ((papier > 0) && (papier < eventende)) { boolean papier_m = true;}
     ics_quelldaten = ics_quelldaten.Substr(eventende,(laenge - eventende)); ! Kürzung der Quelldatei um bereits gefundene Termine
     anfang = ics_quelldaten.Find(sucheanfang);                    ! Ende der while-Schleife und Rücksprung für nächsten Termin am gleichen Tag
}
!  ++++++ Abfrage der zwischengespeicherten Status und Setzen der Systemvariablen  ++++++
       if (bio_m > 0)  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Muelltonne_braun").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Muelltonne_braun").State("false");}
       if (rest_m > 0) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Muelltonne_schwarz").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Muelltonne_schwarz").State("false");}
       if (papier_m > 0) { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Muelltonne_blau").State("true");}
       else  { dom.GetObject(ID_SYSTEM_VARIABLES).Get("Muelltonne_blau").State("false");}
       ics_quelldaten = "";                                        ! Leeren der Scriptvariable
! ===== Programmende =====
Hättest du noch einen Tipp für mich?
Dateianhänge
2.PNG
Systemvariablen
2.PNG (2.69 KiB) 357 mal betrachtet
1.PNG
Kalendereintrag
1.PNG (1.8 KiB) 357 mal betrachtet
492 Kanäle in 92 Geräten und 37 CUxD-Kanäle in 4 CUxD-Geräten:

Xel66
Beiträge: 14169
Registriert: 08.05.2013, 23:33
System: Alternative CCU (auf Basis OCCU)
Wohnort: Nordwürttemberg
Hat sich bedankt: 587 Mal
Danksagung erhalten: 1501 Mal

Re: Systemvariablen für ical Termine setzen (am Beispiel ics eines Google Kalenders) für Mülltermine und Urlaub

Beitrag von Xel66 » 04.02.2024, 16:07

Ich wiederhole mich...
Xel66 hat geschrieben:
03.02.2024, 10:16
Bekommst Du Daten, wenn Du diese URL in einem Browser verwendest?
Wenn dort nichts (die .ics als Download) kommt, kannst Du anlegen, was immer Du willst. Dann funktioniert die Abfrage schon nicht. Dann kann logischerweise der ganze nachgelagerte Krimskram auch nicht funktionieren. Keine Datei als Download, kein Durchsuchen möglich, keine Fundstellen und dann auch kein Systemvariableninhalt.

Gruß Xel66
-------------------------------------------------------------------------------------------
524 Kanäle in 146 Geräten und 267 CUxD-Kanäle in 34 CUxD-Geräten:
343 Programme, 334 Systemvariablen und 183 Direktverknüpfungen,
RaspberryMatic Version: 3.65.11.20221005 + Testsystem: CCU2 2.61.7
-------------------------------------------------------------------------------------------
Einsteigerthread, Programmlogik-Thread, WebUI-Handbuch

Roli01
Beiträge: 102
Registriert: 06.04.2008, 23:56
Wohnort: nähe Krems/Donau
Danksagung erhalten: 3 Mal

Re: Systemvariablen für ical Termine setzen (am Beispiel ics eines Google Kalenders) für Mülltermine und Urlaub

Beitrag von Roli01 » 04.02.2024, 17:32

Hi, ja also wenn ich den Link eingebe dann wird eine basics.ics Datei runtergeladen die ich dann im z.B. Windows Kalender importieren kann und wo auch alle Termine enthalten sind.
492 Kanäle in 92 Geräten und 37 CUxD-Kanäle in 4 CUxD-Geräten:

Xel66
Beiträge: 14169
Registriert: 08.05.2013, 23:33
System: Alternative CCU (auf Basis OCCU)
Wohnort: Nordwürttemberg
Hat sich bedankt: 587 Mal
Danksagung erhalten: 1501 Mal

Re: Systemvariablen für ical Termine setzen (am Beispiel ics eines Google Kalenders) für Mülltermine und Urlaub

Beitrag von Xel66 » 04.02.2024, 18:00

Roli01 hat geschrieben:
04.02.2024, 17:32
Hi, ja also wenn ich den Link eingebe dann wird eine basics.ics Datei runtergeladen...
OK, erst Hürde genommen. Die Systemvariablen haben welchen Typ? Die Namen allein sind nicht hilfreich. Sie müssen Logik-Variablen sein.

Gruß Xel66
-------------------------------------------------------------------------------------------
524 Kanäle in 146 Geräten und 267 CUxD-Kanäle in 34 CUxD-Geräten:
343 Programme, 334 Systemvariablen und 183 Direktverknüpfungen,
RaspberryMatic Version: 3.65.11.20221005 + Testsystem: CCU2 2.61.7
-------------------------------------------------------------------------------------------
Einsteigerthread, Programmlogik-Thread, WebUI-Handbuch

Roli01
Beiträge: 102
Registriert: 06.04.2008, 23:56
Wohnort: nähe Krems/Donau
Danksagung erhalten: 3 Mal

Re: Systemvariablen für ical Termine setzen (am Beispiel ics eines Google Kalenders) für Mülltermine und Urlaub

Beitrag von Roli01 » 04.02.2024, 18:08

Ja , hab ich.
Dateianhänge
3.PNG
492 Kanäle in 92 Geräten und 37 CUxD-Kanäle in 4 CUxD-Geräten:

Antworten

Zurück zu „HomeMatic Tipps & Tricks - keine Fragen!“