daily-briefing/server/routers/homeassistant.py
Sam f6a42c2dd2 feat: add Admin Panel with JWT auth, DB settings, and integration management
Complete admin backend with login, where all integrations (weather, news,
Home Assistant, Vikunja, Unraid, MQTT) can be configured via web UI instead
of ENV variables. Two-layer config: ENV seeds DB on first start, then DB
is source of truth. Auto-migration system on startup.

Backend: db.py shared pool, auth.py JWT, settings_service CRUD, seed_service,
admin router (protected), test_connections per integration, config.py rewrite.

Frontend: react-router v6, login page, admin layout with sidebar, 8 settings
pages (General, Weather, News, HA, Vikunja, Unraid, MQTT, ChangePassword),
shared IntegrationForm + TestButton components.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 10:37:30 +01:00

47 lines
1.2 KiB
Python

"""Home Assistant data router."""
from __future__ import annotations
import logging
from typing import Any, Dict
from fastapi import APIRouter
from server.cache import cache
from server.config import get_settings
from server.services.ha_service import fetch_ha_data
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api", tags=["homeassistant"])
CACHE_KEY = "ha"
@router.get("/ha")
async def get_ha() -> Dict[str, Any]:
"""Return Home Assistant entity data.
The exact shape depends on what ``fetch_ha_data`` returns; on failure an
error stub is returned instead::
{ "error": true, "message": "..." }
"""
# --- cache hit? -----------------------------------------------------------
cached = await cache.get(CACHE_KEY)
if cached is not None:
return cached
# --- cache miss -----------------------------------------------------------
try:
data: Dict[str, Any] = await fetch_ha_data(
get_settings().ha_url,
get_settings().ha_token,
)
except Exception as exc:
logger.exception("Failed to fetch Home Assistant data")
return {"error": True, "message": str(exc)}
await cache.set(CACHE_KEY, data, get_settings().ha_cache_ttl)
return data