Weather: Replace wttr.in with Open-Meteo + structured logging

- Replace wttr.in (unreachable from Docker) with Open-Meteo API
  (free, no API key, reliable) with geocoding cache
- WMO weather codes mapped to German descriptions + emoji icons
- Add [WEATHER], [NEWS], [UNRAID], [DASHBOARD] log prefixes
- Structured integration status table on startup
- Suppress noisy httpx INFO logs (services log their own summaries)
- Add logging to unraid_service (was completely silent on errors)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sam 2026-03-02 17:45:23 +01:00
parent 94cf618e0d
commit d3305a243c
6 changed files with 280 additions and 196 deletions

View file

@ -20,6 +20,10 @@ logging.basicConfig(
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
# Reduce noise from third-party libraries — our services log their own summaries
logging.getLogger("httpx").setLevel(logging.WARNING)
logging.getLogger("httpcore").setLevel(logging.WARNING)
@asynccontextmanager
async def lifespan(app: FastAPI):
@ -61,12 +65,21 @@ async def lifespan(app: FastAPI):
try:
await reload_settings()
cfg = get_settings()
logger.info(
"Settings loaded from DB — %d Unraid servers, MQTT=%s, HA=%s",
len(cfg.unraid_servers),
"enabled" if cfg.mqtt_enabled else "disabled",
"enabled" if cfg.ha_enabled else "disabled",
)
# Structured startup summary
integrations = [
("Weather", True, f"{cfg.weather_location} + {cfg.weather_location_secondary}"),
("HA", cfg.ha_enabled, cfg.ha_url or "not configured"),
("Vikunja", cfg.vikunja_enabled, cfg.vikunja_url or "not configured"),
("Unraid", cfg.unraid_enabled, f"{len(cfg.unraid_servers)} server(s)"),
("MQTT", cfg.mqtt_enabled, f"{cfg.mqtt_host}:{cfg.mqtt_port}" if cfg.mqtt_host else "not configured"),
("News", cfg.news_enabled, f"max_age={cfg.news_max_age_hours}h"),
]
logger.info("--- Integration Status ---")
for name, enabled, detail in integrations:
status = "ON " if enabled else "OFF"
logger.info(" [%s] %-10s %s", status, name, detail)
logger.info("--------------------------")
except Exception:
logger.exception("Failed to load settings from DB — using ENV defaults")
cfg = settings