Danke dir
Smarthome Wolkenlampe mit Wetteranzeige
-
Ich habe vor kurzem ein Video gesehen, in dem jemand eine Lampe gebaut hat, die aussieht wie eine Wolke. Die Idee hat mir super gefallen und da dachte ich mir, ich will das ganze auch umsetzen und nachbauen. Das war relativ einfach.
- 2x Lampenschirme besorgt
- vier Dosen Sprühkleber
- eine Dose Haarspray fürs Finish
- Füllmaterials als “Wolke”
- ein bisschen Heißkleber und Draht zum verbinden der beiden Lampenschirme
Wenn man das alles kombiniert, sieht’s am Ende ungefähr so aus:
Bis zu dem Stand hat das ganze ca. 25€ gekostet. Für so eine stylische Lampe eigentlich Konkurrenzlos.
Fehlen eigentlich nur noch die LED’s im Inneren.
Ich habe mich erstmal für normale RGB-LED-Streifen entschieden.
So weit so gut, nur reicht mir das so noch nicht: Meine Lampe soll smart werden. Und damit herzlich Willkommen zu meiner kleinen Projekt-Dokumentation.
Projekt-Dokumentation:
Meine smarte Wolkenlampe mit Wetteranzeige
Smart bedeutet in dem Fall nicht nur steuerbar über das Handy und per Sprache via Siri, sondern ich möchte, dass meine Wolkenlampe das Wetter und die Uhrzeit widerspiegelt.
Bedeutet im Klartext: Die Wolkenlampe soll mit dem wetter und der Uhrzeit synchronisiert werden. Und das völlig automatisch.
Morgens und Abends soll meine Wolke jeweils in Rot / Orange / Gelb / Lila Farbtönen erleuchten. Wie ein Sonnenauf und -untergang eben aussieht.
Tagsüber soll die Lampe einfach nur in strahlendem weiß leuchten wenn schönes Wetter ist, und gräulich wenn es regnet.
Als Highlight, und um die passende Atmosphäre zu erzeugen, möchte ich, dass die Wolkenlampe zum Blitzen anfängt, wenn es draußen gewittert.
Das ist der Plan, und ungefähr so soll das Farbspiel am Ende aussehen:
Morgens / Abends
Tagsüber
Gewitter / schlechtes Wetter
Realisieren möchte ich das ganze mit WS2812 LED’s und einer API eines Wetteranbieters. Das wird mein erstes WS2812 Projekt, und ich hab richtig bock. Abonniert das Thema wenn ihr wollt, ich werde meine Updates zu dem Projekt hier veröffentlichen.
Aktiviert die Glocke für Benachrichtigungen
Hier gehts weiter:
To be continued…
-
Die Wetter-API
Als API für das aktuelle Wetter habe ich mich für die kostenlose Variante der openweathermap.org entschieden. Ich denke die Anzahl der Anfragen sollte für meinen Zweck hier locker ausreichen. Nach kurzer Recherche im Internet sieht es auch vielversprechend aus was die Zuverlässigkeit und Genauigkeit betrifft.
Hier mal die Leistungen des Free-Plans:
- 60 Anfragen/Minute
- 1.000.000 Anfragen/Monat
- Current Weather
- Minute Forecast 1 hour*
- Hourly Forecast 2 days*
- Daily Forecast 7 days*
- Historical weather 5 days*
(*) auf 1000 Anfragen am Tag beschränkt.
Nach der kostenlosen Registrierung steht der persönliche API-Schlüssel direkt zur Verfügung und kann genutzt werden, um auf die API zuzugreifen.
Der API-Call ist ziemlich einfach und liefert folgendes Ergebnis
http://api.openweathermap.org/data/2.5/weather?q={STADT}&appid={API-TOKEN}
{ "coord": { "lon": 11.58, "lat": 48.14 }, "weather": [{ "id": 800, "main": "Clear", "description": "clear sky", "icon": "01d" }], "base": "stations", "main": { "temp": 300.87, "feels_like": 302.24, "temp_min": 300.37, "temp_max": 301.48, "pressure": 1022, "humidity": 52 }, "visibility": 10000, "wind": { "speed": 1.41, "deg": 339 }, "clouds": { "all": 0 }, "dt": 1600173992, "sys": { "type": 3, "id": 2002112, "country": "DE", "sunrise": 1600145467, "sunset": 1600190802 }, "timezone": 7200, "id": 2867714, "name": "Munich", "cod": 200 }
Man erhält erstaunlich viele Daten mit denen man arbeiten kann. Mehr als ich erwartet hatte. Mal sehen ob man davon noch was sinnvoll verwenden kann, auch für andere Projekte. Erstmal sind für mich aber folgende Objekte relevant:
"sys": { "type": 3, "id": 2002112, "country": "DE", "sunrise": 1600145467, "sunset": 1600190802 } "weather": [{ "id": 800, "main": "Clear", "description": "clear sky", "icon": "01d" }]
Da es in München aktuell super schön ist, werde ich erstmal rausfinden müssen, was mir bei verschiedenen Wetterlagen zurückgegeben wird.
In Hamburg ist es gerade leicht Bewölkt:
"weather": [{ "id": 802, "main": "Clouds", "description": "scattered clouds", "icon": "03n" }], "clouds": { "all": 40 }
In Brynamman (UK) regnet es:
"weather": [{ "id": 500, "main": "Rain", "description": "light rain", "icon": "10d" }], "clouds": { "all": 87 }
Aber bevor ihr jetzt ebenfalls anfängt, die aktuelle Wetterkarte zu studieren wo es regnet oder Gewittert, könnt ihr leichter einen Blick in die API-Dokumentation werfen.
Hier mal die Wetter-Codes und die passenden Bezeichnungen dazu:
https://openweathermap.org/weather-conditionsHier allgemein die Keys und Values und deren Bedeutung:
https://openweathermap.org/weather-data -
API Daten verarbeiten
Ich habe gerade die API in einem Arduino Programm verarbeitet. Entweder läuft das ganze am Ende auf einem ESP01-S oder einem D1 Mini oder Ähnlichem. Je nachdem was die Leistung hergibt.
Der Code holt sich das JSON-Objekt von der API und verarbeitet es dementsprechend weiter. Auf den ersten Blick sieht das Programm ziemlich wild aus, ist aber eigentlich nichts spektakuläres:
#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <ArduinoJson.h> HTTPClient sender; // ##################################################################### // USER DATA USER DATA USER DATA USER DATA USER DATA USER DATA USER DATA // ##################################################################### // WLAN-Daten const char* ssid = "WLAN-SSID"; const char* password = "WLAN-PSK"; // ##################################################################### // home.openweathermap.org/api_keys const int zipcode = 12345; const String apikey = "d96f32a2a42s3832fa0695fx4553c5c4"; // USER DATA USER DATA USER DATA USER DATA USER DATA USER DATA USER DATA // ##################################################################### String json; String city_name; String weather_description; int weather_id; /* * * DEFINITIONEN DER EINZELENEN WETTER-IDs * */ // THUNDERSTORM // GEWITTER int thunderstorm[]={200, 201, 2020, 210, 211, 212, 221, 230, 231, 232}; // DRIZZLE // NIESELREGEN int drizzle[]={300, 301, 302, 310, 311, 312, 313, 314, 321}; // RAIN // REGEN int rain[]={500, 501, 502, 503, 504, 511, 520, 521, 522, 531}; // SNOW // SCHNEE int snow[]={600, 601, 602, 611, 612, 613, 615, 616, 620, 621, 622}; // ATMOSPHERE // ATMOSPHÄRE int atmosphere[]={701, 711, 721, 731, 741, 751, 761, 762, 771, 781}; // CLEAR // KLAR int clear_0[]={800}; // CLOUDS // BEWÖLKT int clouds[]={801, 802, 803, 804}; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print("."); } Serial.println("Verbunden!"); // JSON-Objekt von der API abfragen und in Variable speichern json = get_weather_json(zipcode, apikey); // JSON Objekt ausgeben (DEBUG) Serial.println(json); // Values der Keys in die einzelnen Variablen speichern city_name = get_city_name(json); weather_description = get_weather_description(json); weather_id = get_weather_id(json); // Ausgabe der einzelnen Variablen (DEBUG) Serial.println(city_name + " :: " + weather_description + " :: " + weather_id); //HIER NUR EIN BEISPIEL ZUM VERABRITEN if (std::find(std::begin(thunderstorm), std::end(thunderstorm), weather_id) != std::end(thunderstorm)){ Serial.println("Es ist herrscht ein Gewitter!"); } if (std::find(std::begin(drizzle), std::end(drizzle), weather_id) != std::end(drizzle)){ Serial.println("Es ist herrscht Nieselregen!"); } if (std::find(std::begin(rain), std::end(rain), weather_id) != std::end(rain)){ Serial.println("Es ist regnet!"); } if (std::find(std::begin(snow), std::end(snow), weather_id) != std::end(snow)){ Serial.println("Es ist schneit!"); } if (std::find(std::begin(atmosphere), std::end(atmosphere), weather_id) != std::end(atmosphere)){ Serial.println("Trübe Atmosphäre!"); } if (std::find(std::begin(clear_0), std::end(clear_0), weather_id) != std::end(clear_0)){ Serial.println("Der Himmel ist klar!"); } if (std::find(std::begin(clouds), std::end(clouds), weather_id) != std::end(clouds)){ Serial.println("Es ist (leicht) bewölkt!"); } //HIER NUR EIN BEISPIEL ZUM VERABRITEN } void loop() { } /* * * * ##### DEFINED FUNCTIONS ##### * * */ String get_weather_json(int zipcode, String apikey){ if (sender.begin("http://api.openweathermap.org/data/2.5/weather?zip=" + String(zipcode) + ",DE&appid=" + apikey)) { // HTTP-Code der Response speichern int httpCode = sender.GET(); if (httpCode > 0) { // Anfrage wurde gesendet und Server hat geantwortet // Info: Der HTTP-Code für 'OK' ist 200 if (httpCode == HTTP_CODE_OK) { // Hier wurden die Daten vom Server empfangen // String vom Webseiteninhalt speichern String payload = sender.getString(); // Hier kann mit dem Wert weitergearbeitet werden // ist aber nicht unbedingt notwendig // Serial.println(payload); return payload; } }else{ // Falls HTTP-Error Serial.printf("HTTP-Error: ", sender.errorToString(httpCode).c_str()); } // Wenn alles abgeschlossen ist, wird die Verbindung wieder beendet sender.end(); }else { Serial.printf("HTTP-Verbindung konnte nicht hergestellt werden!"); } } String get_city_name(String input_json){ const size_t capacity = 800; DynamicJsonDocument doc(capacity); const char* json = input_json.c_str(); deserializeJson(doc, json); const char* cityname = doc["name"]; return String(cityname); } String get_weather_description(String input_json){ const size_t capacity = 800; DynamicJsonDocument doc(capacity); const char* json = input_json.c_str(); deserializeJson(doc, json); JsonObject weather_0 = doc["weather"][0]; const char* weather_0_description = weather_0["description"]; return String(weather_0_description); } int get_weather_id(String input_json){ const size_t capacity = 800; DynamicJsonDocument doc(capacity); const char* json = input_json.c_str(); deserializeJson(doc, json); JsonObject weather_0 = doc["weather"][0]; int weather_0_id = weather_0["id"]; return weather_0_id; }
Mit dem folgendem Code-Snippet wird die API abgerufen. Die Einzelnen Werte werden dementsprechend in Variablen gespeichert. Für mich sind nur 3 Values ausschlaggebend.
Der
Ort
, dieWetter-Beschreibung
und dieWetter-ID
.Für den eigentlichen Call und die Ausgabe sind nur die folgenden Zeilen verantwortlich:
// JSON-Objekt von der API abfragen und in Variable speichern json = get_weather_json(zipcode, apikey); // JSON Objekt ausgeben (DEBUG) Serial.println(json); // Values der Keys in die einzelnen Variablen speichern city_name = get_city_name(json); weather_description = get_weather_description(json); weather_id = get_weather_id(json); // Ausgabe der einzelnen Variablen (DEBUG) Serial.println(city_name + " :: " + weather_description + " :: " + weather_id);
München :: few clouds :: 801
Der Rest des Codes sind die definierten Funktionen auf die zugegriffen werden. Also u.a
get_weather_id()
,get_weather_json()
oderget_city_name()
.Ihr könnt das Programm 1:1 kopieren und einfügen und natürlich testen. Ihr müsst nur 4 Parameter anpassen:
// WLAN-Zugangsdaten const char* ssid = "WLAN-SSID"; const char* password = "WLAN-PSK"; // PLZ und API-Key const int zipcode = 12345; const String apikey = "d96f32a2a42s3832fa0695fx4553c5c4";
Ich halte euch auf dem Laufenden.
-
@cooper wann geht es weiter
-
@MichKla Weiß ich noch nicht
momentan fehlt komplett die Motivation. 🥱
-
Mal so n paar Fragen falls ich auf die Idee kommen sollte das nachbaun zu wollen. Auf was läuft die Wetter Api. Auf nem Raspi? Und über was wird die Wolke mit Strom versorgt? Per bliit- und sonnen Energie? Spaß. Per Netzteil oder sogar dierekt 230V? Ich würd mich über antworten freuen. MFG Justin.
-
@justricity mal vorab, sie Lampe läuft nich wie ursprünglich geplant auf WS2812 LEDs sondern normale RGB LEDs. Und hab sie auch nicht mit dem Wetter gesynced weil, keine Ahnung. Früh und Abends ist es bissle planlos bzw. unnötig mit der kleinen Wolke da … und gewittern tuts auch fast nie hier. Also läuft grad einfach nur als RGB Lampe.
Wetter API ist ein Dienst. Steht eigentlich alles hier beschrieben.
Ich verwende nen normalen LED Streifen mit dem Controller hier:
https://makesmart.shop/Magic-Home-RGB-ControllerKönntest aber auch ein Komplettset nehmen:
¹AmazonAnsonsten, naja wenn du halt adressierbare LEDs verwenden möchtest läuft das ganze mit nem 5V Netzteil für entsprechende LEDs und Mikrocontroller. Angesteuert werden die LEDs über eine 3.3V Datenleitung direkt über den Mikrocontroller.
¹Affiliate Link. Affiliate Links sind Referenzen des Autors. Bei Kauf wird eine Provision ausgeschüttet. Mehr Informationen.
-
Hey, bin interessiert die Wolke nachzubauen
Wollte fragen ob die Projektdokumentation noch fortgesetzt wird.
VG