Mit Shelly Scripting kannst du deine smarten Geräte so programmieren, dass eine tageslichtabhängige Automatisierung entsteht, du also auf Sonnenaufgangs- und Sonnenuntergangszeiten reagierst. In diesem Beitrag erkläre ich dir, wie du diese Zeiten aus einem kostenlosen Cloud-Service abrufen und zur Automatisierung deiner Shelly-Geräte nutzen kannst.
Das Beste daran: Mit dieser Lösung kannst du die Funktionalität eines kostenpflichtigen Shelly-Plans ganz einfach selbst nachbauen – kostenlos und flexibel. Egal, ob du eine Lampe bei Sonnenuntergang einschalten oder andere smarte Geräte nach Tageslicht steuern möchtest, diese Anleitung hilft dir, dein Smart Home noch smarter zu machen.
Inhaltsverzeichnis
- Warum die alternative zum kostenpflichtigen Plan?
- kostenfreie Wetter API für das ermitteln der Sonnenaufgangs-/untergangszeit
- Weather Forecast API
- Shelly Script zum auslesen der Daten von Weather Forecast API
- Vergleich der ermittelten Daten mit Wetter.com
- tageslichtabhängige Automatisierung einer Lampe
- Fazit: Shelly Scripting für tageslichtabhängige Automatisierung
- Ausblick: Shelly Scripting mit Lichtsensoren erweitern
Warum die alternative zum kostenpflichtigen Plan?
Du kannst in der Shelly Smart Control App eine Szene erstellen und dabei auf die Sonnenaufgangs und untergangszeit reagieren, das jedoch nur mit einem kostenpflichtigen Plan.
Wenn du nur dieses Feature nutzen möchtest, dann zeige ich dir gerne wie du dir zumindest für diesen Anwendungsfall den Upgrade des Accounts sparst.
kostenfreie Wetter API für das ermitteln der Sonnenaufgangs-/untergangszeit
Es gibt diverse APIs welche die Wetterdaten inkl. der Sonnenaufgangs-/untergangszeit liefern, darunter gibt es viele welche entweder kostenpflichtig oder einen kurzen Testzeitraum haben, nur sehr wenige sind wirklich kostenfrei, dazu zählt derzeit Weather Forecast API.
Für den Abruf der Daten benötigen wir die GeoPosition (Latitude & Longitude) der Stadt in welcher die Daten erhoben werden sollen. Ich habe hierzu Google Maps genutzt dort kannst du via rechtsklick und aus dem Kontextmenü die Position in wenigen Sekunden ermitteln.
Weather Forecast API
Die Seite bietet dir ein Formular an in welchem du die GeoPosition, Zeitzone und die Daten welche du benötigst angibst.
Am ende Erhältst du eine Url in welcher die Daten als Parameter angehangen sind.
https://api.open-meteo.com/v1/forecast?daily=sunrise,sunset&timezone=&forecast_days=1&latitude=52.14146177255682&longitude=10.965723217435045&timezone=Europe%2FBerlin
- GeoPosition > latitude & longitude
- Zeitzone > timezone
- Welcher Tag? > forecast_days
- Welche Daten? > daily > sunrise,sunset
Als Ergebnis erhält man ein JSON aus welchen man die übergebenen Daten entnehmen kann sowie die gewünschten Zeiten für die Sonnenaufgangs-/untergangszeiten.
{ "latitude": 52.14, "longitude": 10.959999, "generationtime_ms": 0.00977516174316406, "utc_offset_seconds": 3600, "timezone": "Europe/Berlin", "timezone_abbreviation": "GMT+1", "elevation": 145, "daily_units": { "time": "iso8601", "sunrise": "iso8601", "sunset": "iso8601" }, "daily": { "time": [ "2025-01-20" ], "sunrise": [ "2025-01-20T08:12" ], "sunset": [ "2025-01-20T16:42" ] } }
Shelly Script zum auslesen der Daten von Weather Forecast API
In den letzten beiden Beiträgen Shelly Scripting #2: Sensordaten in der Cloud speichern und abrufen & Shelly Scripting #3: Stromverbrauch und Sensordaten in der Cloud visualisieren habe ich dir bereits gezeigt wie man mit anderen Cloud Diensten arbeitet und dort Daten via HTTP-Request sendet.
// Breitengrad der gewünschten geografischen Position (z. B. einer Stadt oder Region). let latitude = "52.14146177255682"; // Längengrad der gewünschten geografischen Position. let longitude = "10.965723217435045"; // Zeitzone für die API-Anfrage (URL-encoded, z. B. "Europe/Berlin"). let timezone = "Europe%2FBerlin"; // Basis-URL der Open-Meteo-API. Diese API liefert Wettervorhersagen, inklusive Sonnenaufgangs- und Sonnenuntergangszeiten. // Die Anfrage ist so konfiguriert, dass nur die Daten für den aktuellen Tag abgerufen werden. baseurl = "https://api.open-meteo.com/v1/forecast?daily=sunrise,sunset&timezone=&forecast_days=1" // Ergänzen der URL mit den zuvor definierten Parametern für Breiten- und Längengrad sowie die Zeitzone. baseurl += "&latitude="+latitude; // Hinzufügen des Breitengrads. baseurl += "&longitude="+longitude; // Hinzufügen des Längengrads. baseurl += "&timezone="+timezone; // Hinzufügen der Zeitzone. // HTTP-Request-Parameter definieren. // Die Methode ist "GET", da Daten von der API abgerufen werden. // Die URL ist die vollständige, zuvor generierte API-URL. let parameter = { method: "GET", // HTTP-Methode: GET wird verwendet, um Daten abzurufen. url: baseurl // Die URL enthält die Parameter für Breite, Länge und Zeitzone. }; // Senden des HTTP-Requests an die Open-Meteo-API. Shelly.call( "HTTP.Request", parameter, // HTTP-Request mit den definierten Parametern. function(result, error_code, error_message) { // Callback-Funktion zur Verarbeitung der API-Antwort. // Fehlerbehandlung: Falls ein Fehler auftritt, wird die Fehlermeldung ausgegeben. if (error_code != 0) { print(error_message); // Ausgabe der Fehlermeldung. } else { // Verarbeitung der erfolgreichen API-Antwort. // Die Antwort wird vom JSON-Format in ein JavaScript-Objekt umgewandelt. let json = JSON.parse(result.body); // Abrufen des Datums (heutiges Datum) aus der Antwort. let dateStr = json.daily.time; // Abrufen der Sonnenaufgangszeit als String. let sunriseStr = json.daily.sunrise; // Abrufen der Sonnenuntergangszeit als String. let sunsetStr = json.daily.sunset; // Ausgabe der abgerufenen Informationen im Debug-Log. print("Heute: "+dateStr); // Heutiges Datum. print("Sonnenaufgang: "+sunriseStr); // Sonnenaufgangszeit. print("Sonnenuntergang: "+sunsetStr); // Sonnenuntergangszeit. } } );
Parsen des Datums für die Verwendung in einer Steuerung
Damit wir das Datum, welches in diesem Fall als String im JSON hinterlegt ist, weiterverwenden können, muss dieses geparst werden. Dazu werfen wir einen Blick in die Dokumentation zur Funktion parse am Date Objekt von Espruino.
Description
Parse a date string and return milliseconds since 1970. Data can be either '2011-10-20T14:48:00', '2011-10-20' or 'Mon, 25 Dec 1995 13:30:00 +0430'
Von Weather Forecast API erhalten wir das Datum im
Format 2025-01-20T08:12, wir benötigen zum erfolgreichen parsen des Zeitstempels jedoch zusätzlich die Sekunden. Hier reicht es aus das wir an den String ein „:00“ anhängen.
// Umwandeln der API-Antwort von JSON in ein JavaScript-Objekt. // Die JSON-Antwort enthält die Sonnenaufgangszeit als String. let json = JSON.parse(result.body); // Abrufen der Sonnenaufgangszeit aus der JSON-Antwort. // Der Wert ist eine Zeichenkette (z. B. "2025-01-17T07:45"). let sunriseStr = json.daily.sunrise; // Umwandeln der Sonnenaufgangszeit (String) in ein Date-Objekt. // Da der API-String keine Sekunden enthält, werden ":00" (Sekunden) angehängt. // Ohne Sekundenangabe würde `Date.parse()` den String nicht erfolgreich verarbeiten. let sunriseDate = Date.parse(sunriseStr + ":00"); // Ausgabe des erfolgreich geparsten Date-Objekts als lesbare Zeichenkette. print(sunriseDate.toString());
Als Antwort erhalten wir nun die Millisekunden seit dem 1.1.1970 und damit ein Date Objekt mit welchem wir weiterarbeiten können.
Diese Zeitstempel in Millisekunden teilen wir durch 1000 um diesen auf die Sekunden zu kürzen, und können diesen anschließend über den Unix-Zeitstempel-Rechner validieren.
Vergleich der ermittelten Daten mit Wetter.com
Die ermittelten Daten kann man mit Wetter.com vergleichen um so diese zu validieren. Es gibt hier lediglich einen unterschied von einer Minute welche man vernachlässigen kann.
Weather Forecast API | Wetter.com | |
---|---|---|
Sonnenaufgangszeit | 2025-01-21T08:11 | 21.01.2025 08:11 Uhr |
Sonnenuntergangszeit | 2025-01-21T16:43 | 21.01.2025 16:44 Uhr |
tageslichtabhängige Automatisierung einer Lampe
Nachdem wir die Daten ermittelt für die Sonnenaufgangs-/untergangszeit ermittelt haben, können wir diese nun nutzen um ein anderes Gerät EIN oder AUS zu schalten. Dazu zählen zbsp. Lampen, Rollos oder andere smarte Geräte.
Schritt 1 – Timer erstellen
Zunächst erstellen wir aus dem ermittelten Datum einen Timer welcher dann in der Zukunft einmalig ausgeführt wird. Je nachdem wann das Script ausgeführt wird, ist die ermittelte Zeit für Sonnenaufgang oder Sonnenuntergang in der Vergangenheit. Dafür brauchen wir natürlich keinen Timer stellen daher wird im Code geprüft ob dieser Wert in Millisekunden größer 0 ist.
// Breiten- und Längengrad sowie Zeitzone der gewünschten geografischen Position werden definiert. // Diese Werte werden genutzt, um die Sonnenaufgangs- und -untergangszeiten für diese Position abzurufen. let latitude = "52.14146177255682"; // Breitengrad (z. B. für eine Stadt in Deutschland). let longitude = "10.965723217435045"; // Längengrad (z. B. für eine Stadt in Deutschland). let timezone = "Europe%2FBerlin"; // Zeitzone (URL-encoded), hier für Mitteleuropa. // Basis-URL für die Open-Meteo-API, die Sonnenaufgangs- und Sonnenuntergangszeiten liefert. // Ergänzung der URL mit den Parametern (Breitengrad, Längengrad, Zeitzone und Vorhersagedauer). baseurl = "https://api.open-meteo.com/v1/forecast?daily=sunrise,sunset&timezone=&forecast_days=1" baseurl += "&latitude=" + latitude; // Hinzufügen des Breitengrads. baseurl += "&longitude=" + longitude; // Hinzufügen des Längengrads. baseurl += "&timezone=" + timezone; // Hinzufügen der Zeitzone. // HTTP-Request-Parameter werden definiert. Die Methode ist "GET", um Daten abzurufen. let parameter = { method: "GET", // HTTP-Methode: GET. url: baseurl // Die vollständige URL wird in den Parametern übergeben. }; // Funktion zum Erstellen eines Timers, der zu einer bestimmten Zeit ausgeführt wird. // Parameter: // - date: Zeitpunkt (als Date-Objekt), zu dem der Timer ausgelöst werden soll. // - activate: Boolean, um das Relais ein- oder auszuschalten (true = ein, false = aus). function createTimer(date, activate) { let timestamp = date.toString(); // Konvertieren des Date-Objekts in einen Zeitstempel. let currentDate = Date.now(); // Aktuelle Zeit als UNIX-Zeitstempel (in Millisekunden). let currentTimetamp = currentDate.toString(); // Konvertieren der aktuellen Zeit in einen String. // Berechnung der verbleibenden Zeit bis zur nächsten Aktion in Millisekunden. let action = timestamp - currentTimetamp; print("Zeit bis zur nächsten Ausführung: " + action + "ms."); // Überprüfen, ob die geplante Zeit in der Zukunft liegt. if (action > 0) { // Timer wird erstellt, der die Aktion (Relais schalten) zum richtigen Zeitpunkt ausführt. Timer.set(action, false, function() { let shellyParameter = { id: 0, // ID des Schalters (z. B. Switch 0). on: activate, // Status des Relais: true = einschalten, false = ausschalten. }; // Schalten des Relais mit den definierten Parametern. Shelly.call("Switch.Set", shellyParameter); }); } } // HTTP-Request an die Open-Meteo-API wird gesendet, um Sonnenaufgangs- und -untergangszeiten abzurufen. Shelly.call( "HTTP.Request", parameter, // HTTP-Anfrage mit den Parametern. function(result, error_code, error_message) { // Callback-Funktion zur Verarbeitung der API-Antwort. if (error_code != 0) { // Fehlerfall: Ausgabe der Fehlermeldung im Debug-Log. print(error_message); } else { // Erfolgsfall: Verarbeiten der API-Antwort. let json = JSON.parse(result.body); // Umwandeln der JSON-Antwort in ein JavaScript-Objekt. // Extrahieren des heutigen Datums, der Sonnenaufgangs- und Sonnenuntergangszeiten. let dateStr = json.daily.time; // Heutiges Datum. let sunriseStr = json.daily.sunrise; // Sonnenaufgangszeit (als String). let sunsetStr = json.daily.sunset; // Sonnenuntergangszeit (als String). // Debug-Ausgabe der abgerufenen Daten. print("Heute: " + dateStr); print("Sonnenaufgang: " + sunriseStr); print("Sonnenuntergang: " + sunsetStr); // Konvertieren der Sonnenaufgangs- und -untergangszeiten in Date-Objekte. // Sekunden werden ergänzt (":00"), da die API diese nicht liefert. let sunriseDate = Date.parse(sunriseStr + ":00"); let sunsetDate = Date.parse(sunsetStr + ":00"); // Erstellen von Timern für Sonnenaufgang und Sonnenuntergang. // Beim Sonnenaufgang wird das Relais ausgeschaltet (false). createTimer(sunriseDate, false); // Beim Sonnenuntergang wird das Relais eingeschaltet (true). createTimer(sunsetDate, true); } } );
Schritt 2 – Automatisches laden der Zeiten
Leider gibt es keine Möglichkeit einen Timer mit einer Uhrzeit zu setzen, d.h. wir müssen einen Timer im Hintergrund laufen lassen welcher alle x Minuten prüft ob ein neuer Tag angebrochen ist. Alternativ kann man auch einmalig das Script um 0 Uhr starten und dann den Timer alle 86400000 Millisekunden ausführen.
Timer jede Minute ausführen:
Timer.set(60000, true, function(){...})
Timer alle 86400000 Millisekunden ausführen:
Timer.set(86400000, true, function(){...});
Wenn wir die erste Variante wählen, dann haben wir den Vorteil das wenn der Shelly mal wegen einem Stromausfall neustartet das du dann trotzdem dein Script normal weiterlaufen lassen kannst. Dafür musst du jedoch den Tageswechsel ermitteln.
Ermitteln des neuen Tages mit JavaScript
Da das Date Objekt keine getter für die Werte Tag (Date), Monat (Month) und Jahr (Year) hat, müssen wir aus dem Zeitstempel (die Millisekunden seit 01.01.1970) die jeweiligen Werte berechnen. Dazu muss auch das Schaltjahr berücksichtigt werden!
/** * Funktion zum Berechnen von Tag, Monat und Jahr aus einem Timestamp in Millisekunden. * * @param {number} timestamp - Timestamp in Millisekunden. * @returns {Array} - Array mit [Tag, Monat, Jahr]. */ function extractDateFromTimestamp(timestamp) { // Konstante für die Anzahl der Millisekunden in einem Tag. const MS_PER_DAY = 86400000; // Umrechnen des Timestamps von Millisekunden in Tage (ab dem 1. Januar 1970). let daysSinceEpoch = Math.floor(timestamp / MS_PER_DAY); // Startwerte für die Berechnung (ab dem 1. Januar 1970). let year = 1970; let month = 0; let day = 0; // Anzahl der Tage in jedem Monat (nicht-Schaltjahr). const daysInMonths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // Berechnung des Jahres. while (true) { // Prüfen, ob das aktuelle Jahr ein Schaltjahr ist. let isLeapYear = (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0); // Tage im aktuellen Jahr (365 oder 366 bei Schaltjahr). let daysInYear = isLeapYear ? 366 : 365; // Wenn der Timestamp noch größer als die Tage im aktuellen Jahr ist, ins nächste Jahr wechseln. if (daysSinceEpoch >= daysInYear) { daysSinceEpoch -= daysInYear; year++; } else { break; // Jahr ist gefunden. } } // Berechnung des Monats. for (let i = 0; i < 12; i++) { // Prüfen, ob Februar in diesem Jahr ein Schaltjahr ist. if (i === 1) { let isLeapYear = (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0); daysInMonths[i] = isLeapYear ? 29 : 28; } // Wenn der verbleibende Tagewert kleiner als die Tage im aktuellen Monat ist, Monat gefunden. if (daysSinceEpoch < daysInMonths[i]) { month = i + 1; // Monat ist 1-basiert (1 = Januar, 2 = Februar, ...). day = daysSinceEpoch + 1; // Tag ist ebenfalls 1-basiert. break; } else { daysSinceEpoch -= daysInMonths[i]; // Tage des Monats abziehen. } } // Rückgabe von Tag, Monat und Jahr. return [day, month, year]; } // Initialisierung des Arrays, das das zuletzt verarbeitete Datum speichert. // Das Format ist [Tag, Monat, Jahr]. Zu Beginn ist es auf [0, 0, 0] gesetzt. let lastDate = [0, 0, 0]; // Timer, der alle 2500 Millisekunden (2,5 Sekunden) ausgeführt wird. Timer.set(2500, true, function() { // Abrufen des aktuellen Zeitstempels in Millisekunden (UNIX-Zeitstempel). let currentDate = Date.now(); // Gibt die aktuelle Zeit in Millisekunden zurück. // Umwandeln des Zeitstempels in Sekunden. // Bei Verwendung von Millisekunden wird der Dezimalanteil entfernt, indem der String vor dem Punkt genommen wird. let timestamp = currentDate.toString().split(".")[0]; // Aufrufen der Funktion `extractDateFromTimestamp`, um das Datum aus dem Zeitstempel zu extrahieren. // Das Ergebnis ist ein Array im Format [Tag, Monat, Jahr]. let currentDateArray = extractDateFromTimestamp(timestamp); // Vergleich des aktuellen Datums mit dem zuletzt gespeicherten Datum. // Falls sich Tag, Monat oder Jahr ändern, bedeutet dies, dass ein neuer Tag begonnen hat. if (lastDate[0] != currentDateArray[0] || // Vergleich des Tags. lastDate[1] != currentDateArray[1] || // Vergleich des Monats. lastDate[2] != currentDateArray[2]) { // Vergleich des Jahres. // Wenn ein neuer Tag erkannt wird, wird dies im Debug-Log ausgegeben. print("neuer Tag"); // Das letzte Datum wird auf das aktuelle Datum aktualisiert. lastDate = currentDateArray; } else { // Falls das Datum unverändert bleibt, wird "gleicher Tag" ausgegeben. print("gleicher Tag"); } });
In der Konsole erhält man dann die Ausgabe zunächst von „neuer Tag“ und anschließend „gleicher Tag“. Da das Array zuerst nur mit nullen initialisiert wurde sind die Daten unterschiedlich.
fertiges Shelly Script für eine Tageslichtabhängige Automatisierung einer Lampe
Wenn ein neuer Tag anbricht dann sollen zwei neue Timer erzeugt werden, welche zu den jeweiligen Zeitpunkten einmalig starten.
Wenn ich nun am 22.01.2025 um 7:35 Uhr das Script starte, dann werden die Daten ermittelt und die Timer für die nächsten ausführungen gestartet. D.h. der Timer für das deaktivieren der Lampe startet in 2038051 Millisekunden (33,96 Minuten), für das aktivieren in 32938026 Millisekunden (548,96 Minuten oder 9,14 Stunden).
/** * Funktion zum Berechnen von Tag, Monat und Jahr aus einem Timestamp in Millisekunden. * * @param {number} timestamp - Timestamp in Millisekunden. * @returns {Array} - Array mit [Tag, Monat, Jahr]. */ function extractDateFromTimestamp(timestamp) { // Konstante für die Anzahl der Millisekunden in einem Tag. const MS_PER_DAY = 86400000; // Umrechnen des Timestamps von Millisekunden in Tage (ab dem 1. Januar 1970). let daysSinceEpoch = Math.floor(timestamp / MS_PER_DAY); // Startwerte für die Berechnung (ab dem 1. Januar 1970). let year = 1970; let month = 0; let day = 0; // Anzahl der Tage in jedem Monat (nicht-Schaltjahr). const daysInMonths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // Berechnung des Jahres. while (true) { // Prüfen, ob das aktuelle Jahr ein Schaltjahr ist. let isLeapYear = (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0); // Tage im aktuellen Jahr (365 oder 366 bei Schaltjahr). let daysInYear = isLeapYear ? 366 : 365; // Wenn der Timestamp noch größer als die Tage im aktuellen Jahr ist, ins nächste Jahr wechseln. if (daysSinceEpoch >= daysInYear) { daysSinceEpoch -= daysInYear; year++; } else { break; // Jahr ist gefunden. } } // Berechnung des Monats. for (let i = 0; i < 12; i++) { // Prüfen, ob Februar in diesem Jahr ein Schaltjahr ist. if (i === 1) { let isLeapYear = (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0); daysInMonths[i] = isLeapYear ? 29 : 28; } // Wenn der verbleibende Tagewert kleiner als die Tage im aktuellen Monat ist, Monat gefunden. if (daysSinceEpoch < daysInMonths[i]) { month = i + 1; // Monat ist 1-basiert (1 = Januar, 2 = Februar, ...). day = daysSinceEpoch + 1; // Tag ist ebenfalls 1-basiert. break; } else { daysSinceEpoch -= daysInMonths[i]; // Tage des Monats abziehen. } } // Rückgabe von Tag, Monat und Jahr. return [day, month, year]; } // Initialisierung des Arrays, das das zuletzt verarbeitete Datum speichert. let lastDate = [0, 0, 0]; // Zu Beginn wird ein leeres Datum [0, 0, 0] gesetzt. // Breiten- und Längengrad sowie Zeitzone der gewünschten Position (z. B. Berlin). let latitude = "52.14146177255682"; let longitude = "10.965723217435045"; let timezone = "Europe%2FBerlin"; // Open-Meteo-API URL, um Sonnenaufgangs- und Sonnenuntergangszeiten abzurufen. baseurl = "https://api.open-meteo.com/v1/forecast?daily=sunrise,sunset&timezone=&forecast_days=1"; baseurl += "&latitude=" + latitude; baseurl += "&longitude=" + longitude; baseurl += "&timezone=" + timezone; // HTTP-Parameter für die Anfrage an die API. let parameter = { method: "GET", url: baseurl }; /** * Funktion zum Erstellen eines Timers. * * @param {number} date - Zeitpunkt (als Timestamp in Millisekunden). * @param {boolean} activate - Status des Relais: true = einschalten, false = ausschalten. */ function createTimer(date, activate) { let timestamp = date.toString(); // Konvertieren des Date-Objekts in einen String. let currentDate = Date.now(); // Aktuelle Zeit in Millisekunden. let currentTimetamp = currentDate.toString(); // Umwandeln der aktuellen Zeit in einen String. // Berechnung der verbleibenden Zeit bis zur Timer-Ausführung. let action = timestamp - currentTimetamp; print("Zeit bis zur nächsten Ausführung (" + (activate ? "einschalten" : "ausschalten") + "): " + action + "ms."); if (action > 0) { // Timer wird erstellt und die Aktion ausgeführt, wenn die Zeit erreicht ist. Timer.set(action, false, function() { let shellyParameter = { id: 0, on: activate }; print("Die Lampe wird " + (shellyParameter.on ? "aktiviert" : "deaktiviert")); Shelly.call("Switch.Set", shellyParameter); }); } } /** * Funktion zum Abrufen von Sonnenaufgangs- und Sonnenuntergangszeiten von der Open-Meteo-API. */ function readSunriseSunset() { Shelly.call( "HTTP.Request", parameter, function(result, error_code, error_message) { if (error_code != 0) { // Ausgabe von Fehlern im Debug-Log. print(error_message); } else { let json = JSON.parse(result.body); // JSON-Antwort in ein Objekt umwandeln. let dateStr = json.daily.time; // Heutiges Datum. let sunriseStr = json.daily.sunrise; // Sonnenaufgangszeit als String. let sunsetStr = json.daily.sunset; // Sonnenuntergangszeit als String. // Debug-Ausgabe der abgerufenen Daten. print("Heute: " + dateStr); print("Sonnenaufgang: " + sunriseStr); print("Sonnenuntergang: " + sunsetStr); // Konvertieren der Zeiten in Timestamps (Millisekunden). let sunriseDate = Date.parse(sunriseStr + ":00"); let sunsetDate = Date.parse(sunsetStr + ":00"); // Timer erstellen für Sonnenaufgang und Sonnenuntergang. createTimer(sunriseDate, false); // Relais ausschalten beim Sonnenaufgang. createTimer(sunsetDate, true); // Relais einschalten beim Sonnenuntergang. } } ); } // Timer, der alle 2500 Millisekunden ausgeführt wird, um das Datum zu überprüfen. Timer.set(2500, true, function() { let currentDate = Date.now(); // Aktueller Timestamp in Millisekunden. let timestamp = currentDate.toString().split(".")[0]; // Umwandeln in Sekunden. let currentDateArray = extractDateFromTimestamp(timestamp); // Extrahieren von [Tag, Monat, Jahr]. // Prüfen, ob ein neuer Tag begonnen hat. if (lastDate[0] != currentDateArray[0] || lastDate[1] != currentDateArray[1] || lastDate[2] != currentDateArray[2]) { print("neuer Tag"); lastDate = currentDateArray; // Aktualisieren des letzten Datums. readSunriseSunset(); // Abrufen der neuen Sonnenaufgangs- und Untergangszeiten. } });
Fazit: Shelly Scripting für tageslichtabhängige Automatisierung
Mit diesem Beitrag hast du gelernt, wie du mithilfe von Shelly Scripting tageslichtabhängige Automatisierungen umsetzen kannst. Durch den Zugriff auf kostenlose Cloud-Dienste, wie die Open-Meteo-API, kannst du Sonnenaufgangs- und Sonnenuntergangszeiten für deinen Standort abrufen und für die Steuerung deiner Shelly-Geräte nutzen.
Ein großer Vorteil dieser Methode ist, dass du Funktionen, die normalerweise einen kostenpflichtigen Shelly-Plan erfordern, selbst programmieren kannst – kostenlos und flexibel. Das gezeigte Script ermöglicht es dir, Geräte wie Lampen abhängig vom Tageslicht automatisch ein- oder auszuschalten. Dies macht dein Smart Home nicht nur komfortabler, sondern auch effizienter.
Im nächsten Beitrag werde ich dir zeigen, wie du diese Daten noch weiter verarbeiten kannst, um zusätzliche Smart-Home-Funktionen zu realisieren. Bleib dran, um das volle Potenzial von Shelly Scripting auszuschöpfen!
Ausblick: Shelly Scripting mit Lichtsensoren erweitern
Im nächsten Beitrag möchte ich dir zeigen, wie du den Lichtsensor eines Shelly BLE Motion auslesen kannst. Dieser Sensor bietet nicht nur Bewegungs-, sondern auch Helligkeitsdaten, die ideal für tageslichtabhängige Automatisierungen genutzt werden können.



Falls du den Shelly BLE Motion noch nicht kennst, kannst du in meinem Beitrag „Shelly BLE Motion: Der Bewegungssensor für Ihr Smart Home„ nachlesen, wie du ihn einrichtest und nutzt. Im kommenden Artikel knüpfen wir daran an und integrieren den Lichtsensor in ein Shelly Script, um damit smarte und lichtbasierte Automationen zu erstellen.
Freu dich auf weitere spannende Möglichkeiten, dein Smart Home noch intelligenter zu machen!