from __future__ import annotations from typing import Any from app.cache import cache_get as redis_get, cache_set as redis_set from app.config import ( BRIGHTSKY_BASE_URL, CACHE_TTL_FORECAST, CACHE_TTL_OBSERVATIONS, OPEN_METEO_BASE_URL, ) from app.database import get_cached_json, set_cached_json from app.http_client import fetch_json FORECAST_PARAMS = { "timezone": "Europe/Berlin", "current": "temperature_2m,relative_humidity_2m,apparent_temperature,precipitation,rain,showers,snowfall,weather_code,cloud_cover,pressure_msl,wind_speed_10m,wind_direction_10m,wind_gusts_10m", "hourly": "temperature_2m,relative_humidity_2m,precipitation_probability,precipitation,weather_code,cloud_cover,pressure_msl,wind_speed_10m,wind_direction_10m,wind_gusts_10m,visibility", "daily": "weather_code,temperature_2m_max,temperature_2m_min,precipitation_sum,precipitation_probability_max,wind_speed_10m_max,wind_gusts_10m_max,sunrise,sunset", "forecast_days": 7, } def _coord_key(lat: float, lon: float) -> tuple[float, float]: return round(lat, 4), round(lon, 4) async def get_forecast(lat: float, lon: float) -> dict[str, Any]: lat_k, lon_k = _coord_key(lat, lon) redis_key = f"forecast:{lat_k}:{lon_k}" cached = await redis_get(redis_key) if cached: return {"source": OPEN_METEO_BASE_URL, "lat": lat, "lon": lon, "data": cached, "cached": True} cached = await get_cached_json("forecast_cache", {"lat": lat_k, "lon": lon_k}, CACHE_TTL_FORECAST) if cached: await redis_set(redis_key, cached, CACHE_TTL_FORECAST) return {"source": OPEN_METEO_BASE_URL, "lat": lat, "lon": lon, "data": cached, "cached": True} data = await fetch_json( f"{OPEN_METEO_BASE_URL}/forecast", params={"latitude": lat, "longitude": lon, **FORECAST_PARAMS}, ) await set_cached_json("forecast_cache", {"lat": lat_k, "lon": lon_k}, data) await redis_set(redis_key, data, CACHE_TTL_FORECAST) return {"source": OPEN_METEO_BASE_URL, "lat": lat, "lon": lon, "data": data, "cached": False} async def get_observations(lat: float, lon: float) -> dict[str, Any]: lat_k, lon_k = _coord_key(lat, lon) redis_key = f"observations:{lat_k}:{lon_k}" cached = await redis_get(redis_key) if cached: return {"source": BRIGHTSKY_BASE_URL, "lat": lat, "lon": lon, "data": cached, "cached": True} cached = await get_cached_json("observations_cache", {"lat": lat_k, "lon": lon_k}, CACHE_TTL_OBSERVATIONS) if cached: await redis_set(redis_key, cached, CACHE_TTL_OBSERVATIONS) return {"source": BRIGHTSKY_BASE_URL, "lat": lat, "lon": lon, "data": cached, "cached": True} data = await fetch_json(f"{BRIGHTSKY_BASE_URL}/current_weather", params={"lat": lat, "lon": lon}) await set_cached_json("observations_cache", {"lat": lat_k, "lon": lon_k}, data) await redis_set(redis_key, data, CACHE_TTL_OBSERVATIONS) return {"source": BRIGHTSKY_BASE_URL, "lat": lat, "lon": lon, "data": data, "cached": False}