Replace monolithic Jinja2 template with modern stack: Backend (FastAPI): - Modular router/service architecture - Async PostgreSQL (asyncpg) for news from n8n pipeline - Live Unraid server stats (2 servers via API) - Home Assistant, Vikunja tasks, weather (wttr.in) - WebSocket broadcast for real-time updates (15s) - TTL cache per endpoint, all config via ENV vars Frontend (React + Vite + TypeScript): - Glassmorphism dark theme with Tailwind CSS - Responsive grid: mobile/tablet/desktop/ultrawide - Weather cards, hourly forecast, news with category tabs - Server stats (CPU ring, RAM bar, Docker list) - Home Assistant controls, task management - Live clock, WebSocket connection indicator Infrastructure: - Multi-stage Dockerfile (node:22-alpine + python:3.11-slim) - docker-compose with full ENV configuration - Kaniko CI/CD pipeline for GitLab registry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
47 lines
1.2 KiB
Python
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 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(
|
|
settings.ha_url,
|
|
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, settings.ha_cache_ttl)
|
|
return data
|