diff --git a/aurora-livecam/SettingsManager.php b/aurora-livecam/SettingsManager.php index 0db1f1d..3dc0415 100644 --- a/aurora-livecam/SettingsManager.php +++ b/aurora-livecam/SettingsManager.php @@ -73,6 +73,16 @@ class SettingsManager { 'meta_description' => '', 'meta_keywords' => '' ], + // Weather Widget + 'weather' => [ + 'enabled' => true, + 'api_key' => '', + 'location' => 'Oberdürnten,CH', + 'lat' => '47.2833', + 'lon' => '8.7167', + 'update_interval' => 5, // Minuten + 'units' => 'metric' // metric (Celsius) oder imperial (Fahrenheit) + ], 'last_updated' => null, 'updated_by' => null ]; @@ -239,4 +249,32 @@ class SettingsManager { public function getMetaKeywords() { return $this->get('seo.meta_keywords') ?? ''; } + + // Weather Helper + public function isWeatherEnabled() { + return $this->get('weather.enabled') === true; + } + + public function getWeatherApiKey() { + return $this->get('weather.api_key') ?? ''; + } + + public function getWeatherLocation() { + return $this->get('weather.location') ?? 'Oberdürnten,CH'; + } + + public function getWeatherCoords() { + return [ + 'lat' => $this->get('weather.lat') ?? '47.2833', + 'lon' => $this->get('weather.lon') ?? '8.7167' + ]; + } + + public function getWeatherUpdateInterval() { + return $this->get('weather.update_interval') ?? 5; + } + + public function getWeatherUnits() { + return $this->get('weather.units') ?? 'metric'; + } } diff --git a/aurora-livecam/WeatherManager.php b/aurora-livecam/WeatherManager.php new file mode 100644 index 0000000..4bc6dd0 --- /dev/null +++ b/aurora-livecam/WeatherManager.php @@ -0,0 +1,160 @@ +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; + } + } +} diff --git a/aurora-livecam/index.php b/aurora-livecam/index.php index 5ac8104..d1ee8ad 100644 --- a/aurora-livecam/index.php +++ b/aurora-livecam/index.php @@ -4,12 +4,17 @@ use PHPMailer\PHPMailer\Exception; require __DIR__ . '/vendor/autoload.php'; require_once 'SettingsManager.php'; +require_once 'WeatherManager.php'; // SettingsManager initialisieren $settingsManager = new SettingsManager(); -// AJAX-Handler für Settings (VOR anderen Ausgaben!) +// WeatherManager initialisieren +$weatherManager = new WeatherManager($settingsManager); + +// AJAX-Handler für Settings und Weather (VOR anderen Ausgaben!) $settingsManager->handleAjax(); +$weatherManager->handleAjax(); if (isset($_GET['download_video'])) { $videoDir = './videos/'; @@ -1264,6 +1269,67 @@ class AdminManager { $output .= ''; $output .= ''; // settings-group + // Weather Settings + $output .= '