NEWS
[gelöst] Zeichenfolge aus iCal und DP setzten
-
Hallo zusammen,
Ich würde gerne aus der Instanz ical.2 eine Zeichenfolge als Trigger verwenden.
zB. der Eintrag "VIE - FRA" um 06:50, dieser soll um eine bestimmte Zeit vorher, zB 150min, den Datenpunkt 0_userdata.0.Kalender_options.Reisen.Frühaufsteher auf true setzten und die dazugehörige Zeit in 0_userdata.0.Kalender_options.Reisen.Frühaufsteher_Zeit schreiben.Mit diesem neuen Trigger sollen dann weitere Ereignisse starten, dies ist allerdings nicht mein Problem. Sondern, wie kann ich den Trigger erstellen.
hiermit kann ich das ganze immer nur zu Mitternacht im allgemeinen machen, aber nicht das Setzten zu dem gewünschten Zeitpunkt.
/* Es wird die Instanz iCal.2 auf die Werte VIE-FRA oder VIE-MUC durchsucht. Falls ein Eintrag mit Beginn vor 07:01 gefunden wird, wird der Datenpunkt Frühaufsteher für die Umwälzpumpe aktiviert. Es wird auch die Zeit des Auslöseereignisses gespeichert. Version 1.2. 24.01.2025 */ // Dieser Code wird ausgeführt, wenn sich der Datenpunkt 'ical.2.data.table' ändert on({id: 'ical.2.data.table', change: 'ne'}, function (obj) { let icalData = obj.state.val; // Die neuen Daten des iCal-Datenpunkts // Überprüfen, ob icalData ein Array ist if (Array.isArray(icalData)) { // Durchlaufe die ical-Daten und extrahiere die relevanten Informationen for (let event of icalData) { // Hole die Zusammenfassung des Ereignisses let eventSummary = event._object && event._object.summary ? event._object.summary.val : undefined; // Prüfe, ob ein gültiger eventSummary vorhanden ist if (typeof eventSummary === 'string') { // Hole die Startzeit und konvertiere sie in ein Date-Objekt let eventStart = event._object && event._object.start ? new Date(event._object.start) : undefined; if (eventStart) { // Definiere die Vergleichszeit (07:01) let compareTime = new Date(); compareTime.setHours(7, 1, 0, 0); // 07:01:00 am aktuellen Tag // Überprüfen, ob das Event VIE - FRA oder VIE - MUC ist und die Startzeit vor 07:01 liegt const flightDestinations = ['VIE - FRA', 'VIE - MUC']; // Liste der möglichen Flugziele if (flightDestinations.some(destination => eventSummary.includes(destination)) && eventStart < compareTime) { // Setze die Startzeit in den ioBroker-Datenpunkt Frühaufsteher_Zeit let eventStartTime = eventStart.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}); setState('0_userdata.0.Kalender_options.Reisen.Frühaufsteher_Zeit', eventStartTime); // Setze Frühaufsteher auf true setState('0_userdata.0.Kalender_options.Reisen.Frühaufsteher', true); // Ausgabe zur Bestätigung console.log(`Frühaufsteher für ${eventSummary} gesetzt mit Startzeit ${eventStartTime}`); } } else { console.warn(`Kein gültiger Startzeitpunkt für das Ereignis ${eventSummary}`); } } } } else { console.error('Fehler: ical.2.data.table enthält keine gültigen Array-Daten.'); } });
-
-
@homoran Schreibfehler, sollte eine heissen, hab es korrigiert.
-
@australien sagte in Zeichenfolge aus iCal und DP setzten:
Mit diesem neuen Trigger sollen dann weitere Ereignisse starten, dies ist allerdings nicht mein Problem. Sondern, wie kann ich den Trigger erstellen.
Nur das ich das richtig verstehe. Du erzeugst eine Uhrzeit. Diese liegt in der Zukunft. Und dann willst du das basierend auf dieser Uhrzeit eine Aktion getriggert wird - korrekt ?
Wenn ja - soll dieses auch funktionieren wenn du den DP in den du die Zeit geschrieben hast anderweitig beschreibst, oder nur wenn der auf Grund des oben geposteten Skripts geändert wird
A.
-
@asgothian Genau, wichtig ist eigenlich nur der DP, welcher zu bestimmten Zeit auf true gesetzt werden soll, um dann weitere, verschiedene, Aufgaben zu erledigen.Die Zeit dient nur zur Überprüfung und wird nur von diesem Scrip beschrieben.
Ich könnte natürlich minütlich den ical.2 checken, aber das sollte doch auch einfacher gehen.
-
Ich habe das jetzt mal so gelöst, mit einem timeout, bin aber gerne für "schönere" Lösungen bereit.
Weiters habe ich noch nachgereicht, dass der Trigger nach einer Minute wieder zurückgesetzt wird.// Definiere hier die Minuten, um wie viele Minuten vor dem Event der Datenpunkt gesetzt werden soll const minutesBefore = 30; // Dieser Code wird ausgeführt, wenn sich der Datenpunkt 'ical.2.data.table' ändert on({id: 'ical.2.data.table', change: 'ne'}, function (obj) { let icalData = obj.state.val; // Die neuen Daten des iCal-Datenpunkts // Überprüfen, ob icalData ein Array ist if (Array.isArray(icalData)) { // Durchlaufe die ical-Daten und extrahiere die relevanten Informationen for (let event of icalData) { // Hole die Zusammenfassung des Ereignisses let eventSummary = event._object && event._object.summary ? event._object.summary.val : undefined; // Prüfe, ob ein gültiger eventSummary vorhanden ist if (typeof eventSummary === 'string') { // Hole die Startzeit und konvertiere sie in ein Date-Objekt let eventStart = event._object && event._object.start ? new Date(event._object.start) : undefined; if (eventStart) { // Definiere die Vergleichszeit (07:01) let compareTime = new Date(); compareTime.setHours(7, 1, 0, 0); // 07:01:00 am aktuellen Tag // Überprüfen, ob das Event VIE - FRA oder VIE - MUC ist und die Startzeit vor 07:01 liegt const flightDestinations = ['VIE - FRA', 'VIE - MUC']; // Liste der möglichen Flugziele if (flightDestinations.some(destination => eventSummary.includes(destination)) && eventStart < compareTime) { // Berechne den Zeitpunkt x Minuten vorher let activationTime = new Date(eventStart.getTime() - minutesBefore * 60 * 1000); // Prüfe, ob der berechnete Zeitpunkt in der Zukunft liegt let now = new Date(); if (activationTime > now) { // Berechne die Verzögerung in Millisekunden bis zum Aktivierungszeitpunkt let delay = activationTime.getTime() - now.getTime(); // Setze einen Timer, der den Datenpunkt erst zum Aktivierungszeitpunkt setzt setTimeout(() => { // Setze die Startzeit in den ioBroker-Datenpunkt Frühaufsteher_Zeit let eventStartTime = eventStart.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}); setState('0_userdata.0.Kalender_options.Reisen.Frühaufsteher_Zeit', eventStartTime); // Setze Frühaufsteher auf true setState('0_userdata.0.Kalender_options.Reisen.Frühaufsteher', true); // Ausgabe zur Bestätigung console.log(`Frühaufsteher für ${eventSummary} gesetzt mit Startzeit ${eventStartTime}`); // Timer für das Zurücksetzen auf false nach 1 Minute setTimeout(() => { setState('0_userdata.0.Kalender_options.Reisen.Frühaufsteher', false); console.log(`Frühaufsteher für ${eventSummary} nach 1 Minute wieder deaktiviert.`); }, 60 * 1000); // 1 Minute Verzögerung }, delay); console.log(`Timer für Frühaufsteher gesetzt: ${eventSummary} wird ${minutesBefore} Minuten vor ${eventStart} aktiviert.`); } else { console.log(`Aktivierungszeitpunkt für ${eventSummary} liegt in der Vergangenheit. Frühaufsteher wird sofort aktiviert.`); // Wenn der Zeitpunkt in der Vergangenheit liegt, sofort setzen let eventStartTime = eventStart.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}); setState('0_userdata.0.Kalender_options.Reisen.Frühaufsteher_Zeit', eventStartTime); setState('0_userdata.0.Kalender_options.Reisen.Frühaufsteher', true); // Timer für das Zurücksetzen auf false nach 1 Minute setTimeout(() => { setState('0_userdata.0.Kalender_options.Reisen.Frühaufsteher', false); console.log(`Frühaufsteher für ${eventSummary} nach 1 Minute wieder deaktiviert.`); }, 60 * 1000); // 1 Minute Verzögerung } } } else { console.warn(`Kein gültiger Startzeitpunkt für das Ereignis ${eventSummary}`); } } } } else { console.error('Fehler: ical.2.data.table enthält keine gültigen Array-Daten.'); } });
-
@australien Also - an der stelle wo du die Zeit in den Trigger schreibst kannst du parallel auch einen cron Shedule erzeugen.
Dazu legst du bei Skriptstart eine Variable 'cronHandle' mit dem Wert 'undefined' an.
In deinem Skript kommt dann (direkt da wo du auch den DP Frühaufsteher_zeit setzt)
if (cronHandle) clearShedule(cronHandle); const eventDay = eventStart.toLocaleDateString('de-DE',{year:'numeric', month:'numeric', day:'numeric'}; cronHandle = shedule(`{"time":{"exactTime":true,"start":"${eventStartTime"},"period":{"once":"${eventDay}"}}`, async () => { // hier deine Aktionen zum Event-Zeitpunkt. });
Wichtig - du solltest die shedule syntax verifizieren - in deinem Skript. Zielsyntax ist:
'{"time":{"exactTime":true,"start":"00:00"},"period":{"once":"27.01.2025"}}'A.
Nachtrag:
Du solltest darüber nachdenken die eigenen DP's umzubenennen, so das keine Umlaute enthalten sindA.
2. Nachtrag: deine Lösung mit dem Timeout geht problemlos, geht aber schief wenn die ical2 Data Table warum auch immer nochmal geändert wird bevor der Timeout abläuft. Dann wird der Timeout nicht gelöscht und ein 2. entsteht. -
@asgothian danke für den Hinweis mit den Umlauten, das Script schaut jetzt finalisiert so aus.
/* Es wird die Instanz iCal.2 auf die Werte VIE-FRA oder VIE-MUC durchsucht. Falls ein Eintrag mit Beginn vor 07:01 gefunden wird, wird der Datenpunkt Frühaufsteher für die Umwälzpumpe aktiviert. Es wird auch die Zeit des Auslöseereignisses gespeichert. Version 1.2. 24.01.2025 */ // Definiere hier die Minuten, um wie viele Minuten vor dem Event der Datenpunkt gesetzt werden soll const minutesBefore = 150; // Variablen für die Cron-Handles (wird beim Skriptstart auf undefined gesetzt) let cronHandle; let cronHandleReset; // Dieser Code wird ausgeführt, wenn sich der Datenpunkt 'ical.2.data.table' ändert on({id: 'ical.2.data.table', change: 'ne'}, function (obj) { let icalData = obj.state.val; // Die neuen Daten des iCal-Datenpunkts // Überprüfen, ob icalData ein Array ist if (Array.isArray(icalData)) { // Durchlaufe die ical-Daten und extrahiere die relevanten Informationen for (let event of icalData) { // Hole die Zusammenfassung des Ereignisses let eventSummary = event._object && event._object.summary ? event._object.summary.val : undefined; // Prüfe, ob ein gültiger eventSummary vorhanden ist if (typeof eventSummary === 'string') { // Hole die Startzeit und konvertiere sie in ein Date-Objekt let eventStart = event._object && event._object.start ? new Date(event._object.start) : undefined; if (eventStart) { // Definiere die Vergleichszeit (07:01) let compareTime = new Date(); compareTime.setHours(7, 1, 0, 0); // 07:01:00 am aktuellen Tag // Überprüfen, ob das Event VIE - FRA oder VIE - MUC ist und die Startzeit vor 07:01 liegt const flightDestinations = ['VIE - FRA', 'VIE - MUC']; // Liste der möglichen Flugziele if (flightDestinations.some(destination => eventSummary.includes(destination)) && eventStart < compareTime) { // Berechne den Zeitpunkt x Minuten vorher let activationTime = new Date(eventStart.getTime() - minutesBefore * 60 * 1000); // Prüfe, ob der berechnete Zeitpunkt in der Zukunft liegt let now = new Date(); if (activationTime > now) { // Berechne das Event-Datum und die Startzeit als String const eventDay = activationTime.toLocaleDateString('de-DE', {year: 'numeric', month: '2-digit', day: '2-digit'}); const eventStartTime = activationTime.toLocaleTimeString('de-DE', {hour: '2-digit', minute: '2-digit'}); // Setze die Startzeit in den ioBroker-Datenpunkt earlybird_time setState('0_userdata.0.Kalender_options.Reisen.earlybird_time', eventStartTime); // Lösche den vorherigen Cron-Job, falls vorhanden if (cronHandle) clearSchedule(cronHandle); // Erstelle einen neuen Cron-Schedule, um earlybird auf true zu setzen cronHandle = schedule( `{"time":{"exactTime":true,"start":"${eventStartTime}"},"period":{"once":"${eventDay}"}}`, async () => { // Setze earlybird auf true setState('0_userdata.0.Kalender_options.Reisen.earlybird', true); // Ausgabe zur Bestätigung console.log(`earlybird für ${eventSummary} ausgelöst um ${eventStartTime}.`); // Berechne die Zeit, wann earlybird auf false gesetzt wird (1 Minute später) let resetTime = new Date(activationTime.getTime() + 1 * 60 * 1000); const resetDay = resetTime.toLocaleDateString('de-DE', {year: 'numeric', month: '2-digit', day: '2-digit'}); const resetTimeStr = resetTime.toLocaleTimeString('de-DE', {hour: '2-digit', minute: '2-digit'}); // Lösche den vorherigen Reset-Cron-Job, falls vorhanden if (cronHandleReset) clearSchedule(cronHandleReset); // Erstelle einen neuen Cron-Schedule, um earlybird auf false zu setzen cronHandleReset = schedule( `{"time":{"exactTime":true,"start":"${resetTimeStr}"},"period":{"once":"${resetDay}"}}`, async () => { setState('0_userdata.0.Kalender_options.Reisen.earlybird', false); console.log(`earlybird für ${eventSummary} um ${resetTimeStr} wieder deaktiviert.`); } ); console.log(`Cron-Schedule für Reset von earlybird gesetzt: ${eventSummary} wird am ${resetDay} um ${resetTimeStr} deaktiviert.`); } ); console.log(`Cron-Schedule für earlybird gesetzt: ${eventSummary} wird am ${eventDay} um ${eventStartTime} ausgelöst.`); } else { console.log(`Aktivierungszeitpunkt für ${eventSummary} liegt in der Vergangenheit. earlybird wird sofort aktiviert.`); // Wenn der Zeitpunkt in der Vergangenheit liegt, sofort setzen let eventStartTime = eventStart.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}); setState('0_userdata.0.Kalender_options.Reisen.earlybird_time', eventStartTime); setState('0_userdata.0.Kalender_options.Reisen.earlybird', true); // Berechne die Zeit, wann earlybird auf false gesetzt wird (1 Minute später) let resetTime = new Date(now.getTime() + 1 * 60 * 1000); const resetTimeStr = resetTime.toLocaleTimeString('de-DE', {hour: '2-digit', minute: '2-digit'}); // Lösche den vorherigen Reset-Cron-Job, falls vorhanden if (cronHandleReset) clearSchedule(cronHandleReset); // Erstelle einen neuen Cron-Schedule, um earlybird auf false zu setzen cronHandleReset = schedule( `{"time":{"exactTime":true,"start":"${resetTimeStr}"},"period":{"once":"${resetTime.toLocaleDateString('de-DE', {year: 'numeric', month: '2-digit', day: '2-digit'})}"}}`, async () => { setState('0_userdata.0.Kalender_options.Reisen.earlybird', false); console.log(`earlybird für ${eventSummary} um ${resetTimeStr} wieder deaktiviert.`); } ); console.log(`earlybird für ${eventSummary} wird sofort ausgelöst und am ${resetTimeStr} zurückgesetzt.`); } } } else { console.warn(`Kein gültiger Startzeitpunkt für das Ereignis ${eventSummary}`); } } } } else { console.error('Fehler: ical.2.data.table enthält keine gültigen Array-Daten.'); } });
-
@australien interessant - aber das zurück setzen sollte wegen der kurzen Zeitspanne (1 Min) direkt im Code-Pfad des setzen passieren. Dafür einen extra cron anzulegen ist eher wenig Sinnvoll. Timeout ist da besser
/* Es wird die Instanz iCal.2 auf die Werte VIE-FRA oder VIE-MUC durchsucht. Falls ein Eintrag mit Beginn vor 07:01 gefunden wird, wird der Datenpunkt Frühaufsteher für die Umwälzpumpe aktiviert. Es wird auch die Zeit des Auslöseereignisses gespeichert. {1} Version 1.2. 24.01.2025 */ // Definiere hier die Minuten, um wie viele Minuten vor dem Event der Datenpunkt gesetzt werden soll const minutesBefore = 150; // Variablen für die Cron-Handles (wird beim Skriptstart auf undefined gesetzt) let cronHandle; let cronHandleReset; // Dieser Code wird ausgeführt, wenn sich der Datenpunkt 'ical.2.data.table' ändert on({id: 'ical.2.data.table', change: 'ne'}, function (obj) { let icalData = obj.state.val; // Die neuen Daten des iCal-Datenpunkts // Überprüfen, ob icalData ein Array ist if (Array.isArray(icalData)) { // Durchlaufe die ical-Daten und extrahiere die relevanten Informationen for (let event of icalData) { // Hole die Zusammenfassung des Ereignisses let eventSummary = event._object && event._object.summary ? event._object.summary.val : undefined; // Prüfe, ob ein gültiger eventSummary vorhanden ist if (typeof eventSummary === 'string') { // Hole die Startzeit und konvertiere sie in ein Date-Objekt let eventStart = event._object && event._object.start ? new Date(event._object.start) : undefined; if (eventStart) { // Definiere die Vergleichszeit (07:01) let compareTime = new Date(); compareTime.setHours(7, 1, 0, 0); // 07:01:00 am aktuellen Tag // Überprüfen, ob das Event VIE - FRA oder VIE - MUC ist und die Startzeit vor 07:01 liegt const flightDestinations = ['VIE - FRA', 'VIE - MUC']; // Liste der möglichen Flugziele if (flightDestinations.some(destination => eventSummary.includes(destination)) && eventStart < compareTime) { // Berechne den Zeitpunkt x Minuten vorher let activationTime = new Date(eventStart.getTime() - minutesBefore * 60 * 1000); // Prüfe, ob der berechnete Zeitpunkt in der Zukunft liegt let now = new Date(); if (activationTime > now) { // Berechne das Event-Datum und die Startzeit als String const eventDay = activationTime.toLocaleDateString('de-DE', {year: 'numeric', month: '2-digit', day: '2-digit'}); const eventStartTime = activationTime.toLocaleTimeString('de-DE', {hour: '2-digit', minute: '2-digit'}); // Setze die Startzeit in den ioBroker-Datenpunkt earlybird_time setState('0_userdata.0.Kalender_options.Reisen.earlybird_time', eventStartTime); // Lösche den vorherigen Cron-Job, falls vorhanden if (cronHandle) clearSchedule(cronHandle); // Erstelle einen neuen Cron-Schedule, um earlybird auf true zu setzen cronHandle = schedule( `{"time":{"exactTime":true,"start":"${eventStartTime}"},"period":{"once":"${eventDay}"}}`, async () => { // Setze earlybird auf true setState('0_userdata.0.Kalender_options.Reisen.earlybird', true); // Ausgabe zur Bestätigung console.log(`earlybird für ${eventSummary} ausgelöst um ${eventStartTime}.`); // Berechne die Zeit, wann earlybird auf false gesetzt wird (1 Minute später) let resetTime = new Date(activationTime.getTime() + 1 * 60 * 1000); const resetDay = resetTime.toLocaleDateString('de-DE', {year: 'numeric', month: '2-digit', day: '2-digit'}); const resetTimeStr = resetTime.toLocaleTimeString('de-DE', {hour: '2-digit', minute: '2-digit'}); // Lösche den vorherigen Reset-Cron-Job, falls vorhanden if (cronHandleReset) clearTimeout(cronHandleReset); // Erstelle einen neuen Cron-Schedule, um earlybird auf false zu setzen cronHandleReset = setTimeout(async () => { setState('0_userdata.0.Kalender_options.Reisen.earlybird', false); console.log(`earlybird für ${eventSummary} um ${resetTimeStr} wieder deaktiviert.`); }, 3600000); console.log(`Cron-Schedule für Reset von earlybird gesetzt: ${eventSummary} wird am ${resetDay} um ${resetTimeStr} deaktiviert.`); } ); console.log(`Cron-Schedule für earlybird gesetzt: ${eventSummary} wird am ${eventDay} um ${eventStartTime} ausgelöst.`); } else { console.log(`Aktivierungszeitpunkt für ${eventSummary} liegt in der Vergangenheit. earlybird wird sofort aktiviert.`); // Wenn der Zeitpunkt in der Vergangenheit liegt, sofort setzen let eventStartTime = eventStart.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}); setState('0_userdata.0.Kalender_options.Reisen.earlybird_time', eventStartTime); setState('0_userdata.0.Kalender_options.Reisen.earlybird', true); // Berechne die Zeit, wann earlybird auf false gesetzt wird (1 Minute später) let resetTime = new Date(now.getTime() + 1 * 60 * 1000); const resetTimeStr = resetTime.toLocaleTimeString('de-DE', {hour: '2-digit', minute: '2-digit'}); // Lösche den vorherigen Reset-Cron-Job, falls vorhanden if (cronHandleReset) clearTimeout(cronHandleReset); // Erstelle einen neuen Cron-Schedule, um earlybird auf false zu setzen cronHandleReset = setTimeout(async () => { setState('0_userdata.0.Kalender_options.Reisen.earlybird', false); console.log(`earlybird für ${eventSummary} um ${resetTimeStr} wieder deaktiviert.`); }, 3600000); console.log(`earlybird für ${eventSummary} wird sofort ausgelöst und am ${resetTimeStr} zurückgesetzt.`); } } } else { console.warn(`Kein gültiger Startzeitpunkt für das Ereignis ${eventSummary}`); } } } } else { console.error('Fehler: ical.2.data.table enthält keine gültigen Array-Daten.'); } });