v.0.3.0 Library WeatherData
This commit is contained in:
7
lib/WeatherData/library.json
Normal file
7
lib/WeatherData/library.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "BlinkLed",
|
||||
"version": "1.0.0",
|
||||
"description": "A simple LED control library with internal LED helper.",
|
||||
"authors": [{ "name": "TiiJay14" }],
|
||||
"frameworks": "arduino"
|
||||
}
|
||||
187
lib/WeatherData/src/WeatherFetcher.cpp
Normal file
187
lib/WeatherData/src/WeatherFetcher.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
#include "WeatherFetcher.h"
|
||||
#include <WiFi.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include <ColorSerial.h>
|
||||
|
||||
WeatherFetcher::WeatherFetcher(const char *api_key) : API_KEY(api_key) {}
|
||||
|
||||
bool WeatherFetcher::connectToWiFi(const char *ssid, const char *password)
|
||||
{
|
||||
ColorSerial::info("Verbinde mit WiFi: ");
|
||||
ColorSerial::info(ssid);
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
int attempts = 0;
|
||||
while (WiFi.status() != WL_CONNECTED && attempts < 20)
|
||||
{
|
||||
delay(1000);
|
||||
ColorSerial::info(".");
|
||||
attempts++;
|
||||
}
|
||||
|
||||
ColorSerial::wifiStatus();
|
||||
|
||||
return WiFi.status() == WL_CONNECTED;
|
||||
}
|
||||
|
||||
Weather WeatherFetcher::actual_weather(const char *city, const char *lang, bool test_mode)
|
||||
{
|
||||
if (test_mode)
|
||||
{
|
||||
return create_test_weather();
|
||||
}
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
Serial.println("Keine WiFi Verbindung!");
|
||||
return weather;
|
||||
}
|
||||
|
||||
String weather_url =
|
||||
"https://api.weatherapi.com/v1/current.json?key=" + String(API_KEY) +
|
||||
"&q=" + String(city) + "&aqi=yes&lang=" + String(lang);
|
||||
|
||||
Serial.println("Hole Wetterdaten von: " + weather_url);
|
||||
|
||||
String json_data = fetch_from_url(weather_url);
|
||||
|
||||
if (!json_data.isEmpty())
|
||||
{
|
||||
weather = parse_weather_json(json_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Fehler beim Abrufen der Wetterdaten!");
|
||||
}
|
||||
|
||||
return weather;
|
||||
}
|
||||
|
||||
String WeatherFetcher::fetch_from_url(const String &url)
|
||||
{
|
||||
HTTPClient http;
|
||||
String payload = "";
|
||||
|
||||
http.begin(url);
|
||||
http.setTimeout(10000);
|
||||
|
||||
int httpCode = http.GET();
|
||||
|
||||
if (httpCode == HTTP_CODE_OK)
|
||||
{
|
||||
payload = http.getString();
|
||||
Serial.println("Daten erfolgreich empfangen");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.printf("HTTP Fehler: %d\n", httpCode);
|
||||
Serial.println(http.errorToString(httpCode));
|
||||
}
|
||||
|
||||
http.end();
|
||||
return payload;
|
||||
}
|
||||
|
||||
Weather WeatherFetcher::parse_weather_json(const String &json_data)
|
||||
{
|
||||
Weather weather;
|
||||
|
||||
const size_t capacity = JSON_OBJECT_SIZE(20) + JSON_OBJECT_SIZE(10) + JSON_OBJECT_SIZE(15) + 2048;
|
||||
DynamicJsonDocument doc(capacity);
|
||||
|
||||
DeserializationError error = deserializeJson(doc, json_data);
|
||||
|
||||
if (error)
|
||||
{
|
||||
Serial.print("JSON Parsing fehlgeschlagen: ");
|
||||
Serial.println(error.c_str());
|
||||
return weather;
|
||||
}
|
||||
|
||||
// Location Daten parsen - jetzt direkt mit Arduino String
|
||||
if (doc.containsKey("location"))
|
||||
{
|
||||
JsonObject location = doc["location"];
|
||||
weather.location.name = location["name"].as<String>();
|
||||
weather.location.region = location["region"].as<String>();
|
||||
weather.location.country = location["country"].as<String>();
|
||||
weather.location.localtime = location["localtime"].as<String>();
|
||||
}
|
||||
|
||||
// Current Condition Daten parsen
|
||||
if (doc.containsKey("current"))
|
||||
{
|
||||
JsonObject current = doc["current"];
|
||||
weather.current.last_updated = current["last_updated"].as<String>();
|
||||
weather.current.temp_c = current["temp_c"].as<float>();
|
||||
weather.current.is_day = current["is_day"].as<int>();
|
||||
weather.current.wind_kph = current["wind_kph"].as<float>();
|
||||
weather.current.wind_dir = current["wind_dir"].as<String>();
|
||||
weather.current.pressure_mb = current["pressure_mb"].as<float>();
|
||||
weather.current.humidity = current["humidity"].as<int>();
|
||||
weather.current.cloud = current["cloud"].as<int>();
|
||||
weather.current.feelslike_c = current["feelslike_c"].as<float>();
|
||||
|
||||
// Condition Daten parsen
|
||||
if (current.containsKey("condition"))
|
||||
{
|
||||
JsonObject condition = current["condition"];
|
||||
weather.current.condition.text = condition["text"].as<String>();
|
||||
weather.current.condition.icon = condition["icon"].as<String>();
|
||||
}
|
||||
|
||||
// Air Quality Daten parsen
|
||||
if (current.containsKey("air_quality"))
|
||||
{
|
||||
JsonObject air_quality = current["air_quality"];
|
||||
weather.current.air_quality.co = air_quality["co"].as<float>();
|
||||
weather.current.air_quality.no2 = air_quality["no2"].as<float>();
|
||||
weather.current.air_quality.o3 = air_quality["o3"].as<float>();
|
||||
weather.current.air_quality.so2 = air_quality["so2"].as<float>();
|
||||
weather.current.air_quality.pm2_5 = air_quality["pm2_5"].as<float>();
|
||||
weather.current.air_quality.pm10 = air_quality["pm10"].as<float>();
|
||||
weather.current.air_quality.us_epa_index = air_quality["us-epa-index"].as<int>();
|
||||
weather.current.air_quality.gb_defra_index = air_quality["gb-defra-index"].as<int>();
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("Wetterdaten erfolgreich geparsed");
|
||||
return weather;
|
||||
}
|
||||
|
||||
Weather WeatherFetcher::create_test_weather()
|
||||
{
|
||||
Weather test_weather;
|
||||
|
||||
test_weather.location.name = "Grosshansdorf";
|
||||
test_weather.location.region = "Schleswig-Holstein";
|
||||
test_weather.location.country = "Germany";
|
||||
test_weather.location.localtime = "2023-10-01 12:30";
|
||||
|
||||
test_weather.current.last_updated = "2023-10-01 12:30";
|
||||
test_weather.current.temp_c = 15.5;
|
||||
test_weather.current.is_day = 1;
|
||||
test_weather.current.condition.text = "Sonnig";
|
||||
test_weather.current.condition.icon = "//cdn.weatherapi.com/weather/64x64/day/113.png";
|
||||
test_weather.current.wind_kph = 12.3;
|
||||
test_weather.current.wind_dir = "NW";
|
||||
test_weather.current.pressure_mb = 1013.0;
|
||||
test_weather.current.humidity = 65;
|
||||
test_weather.current.cloud = 10;
|
||||
test_weather.current.feelslike_c = 15.2;
|
||||
|
||||
test_weather.current.air_quality.co = 250.0;
|
||||
test_weather.current.air_quality.no2 = 12.5;
|
||||
test_weather.current.air_quality.o3 = 45.2;
|
||||
test_weather.current.air_quality.so2 = 2.1;
|
||||
test_weather.current.air_quality.pm2_5 = 8.5;
|
||||
test_weather.current.air_quality.pm10 = 12.3;
|
||||
test_weather.current.air_quality.us_epa_index = 1;
|
||||
test_weather.current.air_quality.gb_defra_index = 2;
|
||||
|
||||
Serial.println("Test-Wetterdaten generiert");
|
||||
return test_weather;
|
||||
}
|
||||
27
lib/WeatherData/src/WeatherFetcher.h
Normal file
27
lib/WeatherData/src/WeatherFetcher.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef WEATHER_FETCHER_H
|
||||
#define WEATHER_FETCHER_H
|
||||
|
||||
#include "WeatherStructs.h"
|
||||
#include <WiFi.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class WeatherFetcher
|
||||
{
|
||||
private:
|
||||
Weather weather;
|
||||
const char *API_KEY;
|
||||
|
||||
public:
|
||||
WeatherFetcher(const char *api_key);
|
||||
bool connectToWiFi(const char *ssid, const char *password);
|
||||
Weather actual_weather(const char *city = "grosshansdorf",
|
||||
const char *lang = "de",
|
||||
bool test_mode = false);
|
||||
|
||||
private:
|
||||
String fetch_from_url(const String &url);
|
||||
Weather parse_weather_json(const String &json_data);
|
||||
Weather create_test_weather();
|
||||
};
|
||||
|
||||
#endif
|
||||
53
lib/WeatherData/src/WeatherStructs.h
Normal file
53
lib/WeatherData/src/WeatherStructs.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef WEATHERSTRUCTS_H
|
||||
#define WEATHERSTRUCTS_H
|
||||
|
||||
#include <optional>
|
||||
|
||||
struct Location
|
||||
{
|
||||
String name = "";
|
||||
String region = "";
|
||||
String country = "";
|
||||
String localtime = "";
|
||||
};
|
||||
|
||||
struct Condition
|
||||
{
|
||||
std::optional<String> text;
|
||||
std::optional<String> icon;
|
||||
};
|
||||
|
||||
struct AirQuality
|
||||
{
|
||||
double co = 0.0;
|
||||
double no2 = 0.0;
|
||||
double o3 = 0.0;
|
||||
double so2 = 0.0;
|
||||
double pm2_5 = 0.0;
|
||||
double pm10 = 0.0;
|
||||
int us_epa_index = 0;
|
||||
int gb_defra_index = 0;
|
||||
};
|
||||
|
||||
struct CurrentCondition
|
||||
{
|
||||
String last_updated;
|
||||
double temp_c = 0.0;
|
||||
int is_day = 0;
|
||||
Condition condition;
|
||||
double wind_kph = 0.0;
|
||||
String wind_dir;
|
||||
double pressure_mb = 0.0;
|
||||
int humidity = 0;
|
||||
int cloud = 0;
|
||||
double feelslike_c = 0.0;
|
||||
AirQuality air_quality;
|
||||
};
|
||||
|
||||
struct Weather
|
||||
{
|
||||
Location location;
|
||||
CurrentCondition current;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user