7eda2fbbe8
Implementiert vollständiges Wetter-Widget oberhalb des Webcam-Videos: **Features:** 🌤️ **Wetter-Anzeige:** - Temperatur (°C) - Windgeschwindigkeit & Richtung (km/h) - Luftdruck (hPa) - Luftfeuchtigkeit (%) - Wetterbeschreibung mit Emoji-Icons - Niederschlag (Regen/Schnee) wenn vorhanden ⚙️ **Technisch:** - OpenWeatherMap API Integration - 5 Minuten Cache (konfigurierbar) - Auto-Update alle X Minuten (Frontend) - WeatherManager Klasse für Backend - Schönes Gradient-Design mit Hover-Effekten - Responsive für Mobile 🎛️ **Admin-Settings:** - Wetter-Widget ein/aus - API Key Eingabefeld + Registrierungs-Link - Standort konfigurierbar (Stadt,Land) - GPS-Koordinaten (Lat/Lon) - Update-Intervall (5-60 Minuten) - Einheiten (Metrisch/Imperial) **Dateien:** - WeatherManager.php: Neue Klasse für API-Calls & Caching - SettingsManager.php: Weather Settings Defaults & Helper - index.php: Widget HTML, CSS, JavaScript Auto-Update - settings.json: Weather Defaults initialisiert **Koordinaten Oberdürnten:** Lat: 47.2833, Lon: 8.7167 **Setup für User:** 1. Gratis Account auf openweathermap.org erstellen 2. API Key im Admin-Panel einfügen 3. Fertig! Widget zeigt Live-Wetter an
161 lines
5.1 KiB
PHP
161 lines
5.1 KiB
PHP
<?php
|
|
/**
|
|
* WeatherManager - Holt und cached Wetterdaten von OpenWeatherMap
|
|
*/
|
|
class WeatherManager {
|
|
private $settingsManager;
|
|
private $cacheFile = 'weather_cache.json';
|
|
private $cacheTime = 300; // 5 Minuten in Sekunden
|
|
|
|
public function __construct($settingsManager) {
|
|
$this->settingsManager = $settingsManager;
|
|
}
|
|
|
|
/**
|
|
* Holt aktuelle Wetterdaten (cached)
|
|
*/
|
|
public function getCurrentWeather() {
|
|
// Prüfe ob Weather aktiviert ist
|
|
if (!$this->settingsManager->isWeatherEnabled()) {
|
|
return null;
|
|
}
|
|
|
|
// Prüfe API Key
|
|
$apiKey = $this->settingsManager->getWeatherApiKey();
|
|
if (empty($apiKey)) {
|
|
return ['error' => 'API Key fehlt'];
|
|
}
|
|
|
|
// Prüfe Cache
|
|
$cached = $this->getCache();
|
|
if ($cached !== null) {
|
|
return $cached;
|
|
}
|
|
|
|
// Hole frische Daten von API
|
|
$coords = $this->settingsManager->getWeatherCoords();
|
|
$units = $this->settingsManager->getWeatherUnits();
|
|
|
|
$url = "https://api.openweathermap.org/data/2.5/weather?lat={$coords['lat']}&lon={$coords['lon']}&units={$units}&appid={$apiKey}&lang=de";
|
|
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
|
|
|
$response = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
|
|
if ($httpCode !== 200 || !$response) {
|
|
return ['error' => 'API Fehler'];
|
|
}
|
|
|
|
$data = json_decode($response, true);
|
|
if (!$data || !isset($data['main'])) {
|
|
return ['error' => 'Ungültige API Antwort'];
|
|
}
|
|
|
|
// Formatiere Daten
|
|
$weather = [
|
|
'temp' => round($data['main']['temp'], 1),
|
|
'feels_like' => round($data['main']['feels_like'], 1),
|
|
'humidity' => $data['main']['humidity'],
|
|
'pressure' => $data['main']['pressure'],
|
|
'wind_speed' => round($data['wind']['speed'] * 3.6, 1), // m/s -> km/h
|
|
'wind_deg' => $data['wind']['deg'] ?? 0,
|
|
'wind_direction' => $this->getWindDirection($data['wind']['deg'] ?? 0),
|
|
'clouds' => $data['clouds']['all'] ?? 0,
|
|
'description' => ucfirst($data['weather'][0]['description'] ?? 'Unbekannt'),
|
|
'icon' => $data['weather'][0]['icon'] ?? '01d',
|
|
'rain_1h' => $data['rain']['1h'] ?? 0,
|
|
'snow_1h' => $data['snow']['1h'] ?? 0,
|
|
'location' => $data['name'] ?? $this->settingsManager->getWeatherLocation(),
|
|
'timestamp' => time()
|
|
];
|
|
|
|
// Cache speichern
|
|
$this->saveCache($weather);
|
|
|
|
return $weather;
|
|
}
|
|
|
|
/**
|
|
* Wandelt Windrichtung (Grad) in Kompassrichtung um
|
|
*/
|
|
private function getWindDirection($deg) {
|
|
$directions = ['N', 'NNO', 'NO', 'ONO', 'O', 'OSO', 'SO', 'SSO', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'];
|
|
$index = round($deg / 22.5) % 16;
|
|
return $directions[$index];
|
|
}
|
|
|
|
/**
|
|
* Holt Daten aus Cache (wenn noch gültig)
|
|
*/
|
|
private function getCache() {
|
|
if (!file_exists($this->cacheFile)) {
|
|
return null;
|
|
}
|
|
|
|
$content = file_get_contents($this->cacheFile);
|
|
$data = json_decode($content, true);
|
|
|
|
if (!$data || !isset($data['timestamp'])) {
|
|
return null;
|
|
}
|
|
|
|
// Update-Intervall aus Settings holen (in Minuten)
|
|
$updateInterval = $this->settingsManager->getWeatherUpdateInterval() * 60; // Minuten -> Sekunden
|
|
|
|
// Prüfe ob Cache noch gültig
|
|
if (time() - $data['timestamp'] < $updateInterval) {
|
|
return $data;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Speichert Daten im Cache
|
|
*/
|
|
private function saveCache($data) {
|
|
$json = json_encode($data, JSON_PRETTY_PRINT);
|
|
file_put_contents($this->cacheFile, $json, LOCK_EX);
|
|
}
|
|
|
|
/**
|
|
* Gibt Wetter-Icon-Emoji zurück
|
|
*/
|
|
public function getWeatherEmoji($iconCode) {
|
|
$map = [
|
|
'01d' => '☀️', '01n' => '🌙',
|
|
'02d' => '⛅', '02n' => '☁️',
|
|
'03d' => '☁️', '03n' => '☁️',
|
|
'04d' => '☁️', '04n' => '☁️',
|
|
'09d' => '🌧️', '09n' => '🌧️',
|
|
'10d' => '🌦️', '10n' => '🌧️',
|
|
'11d' => '⛈️', '11n' => '⛈️',
|
|
'13d' => '❄️', '13n' => '❄️',
|
|
'50d' => '🌫️', '50n' => '🌫️'
|
|
];
|
|
return $map[$iconCode] ?? '🌤️';
|
|
}
|
|
|
|
/**
|
|
* AJAX Handler für Wetter-Updates
|
|
*/
|
|
public function handleAjax() {
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'GET') return;
|
|
if (!isset($_GET['weather_action'])) return;
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
if ($_GET['weather_action'] === 'get') {
|
|
$weather = $this->getCurrentWeather();
|
|
echo json_encode(['success' => true, 'data' => $weather]);
|
|
exit;
|
|
}
|
|
}
|
|
}
|