dynamic dashboard initial
This commit is contained in:
@@ -1,11 +1,17 @@
|
||||
"""UI main entry point."""
|
||||
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.responses import HTMLResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
|
||||
from apps.ui.api_client import fetch_devices, fetch_layout
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Initialize FastAPI app
|
||||
app = FastAPI(
|
||||
title="Home Automation UI",
|
||||
@@ -17,18 +23,91 @@ app = FastAPI(
|
||||
templates_dir = Path(__file__).parent / "templates"
|
||||
templates = Jinja2Templates(directory=str(templates_dir))
|
||||
|
||||
# Setup static files
|
||||
static_dir = Path(__file__).parent / "static"
|
||||
static_dir.mkdir(exist_ok=True)
|
||||
app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")
|
||||
|
||||
|
||||
@app.get("/", response_class=HTMLResponse)
|
||||
async def index(request: Request) -> HTMLResponse:
|
||||
"""Render the main UI page.
|
||||
"""Redirect to dashboard.
|
||||
|
||||
Args:
|
||||
request: The FastAPI request object
|
||||
|
||||
Returns:
|
||||
HTMLResponse: Rendered HTML template
|
||||
HTMLResponse: Rendered dashboard
|
||||
"""
|
||||
return templates.TemplateResponse("index.html", {"request": request})
|
||||
return await dashboard(request)
|
||||
|
||||
|
||||
@app.get("/dashboard", response_class=HTMLResponse)
|
||||
async def dashboard(request: Request) -> HTMLResponse:
|
||||
"""Render the dashboard with rooms and devices.
|
||||
|
||||
Args:
|
||||
request: The FastAPI request object
|
||||
|
||||
Returns:
|
||||
HTMLResponse: Rendered dashboard template
|
||||
"""
|
||||
try:
|
||||
# Load layout from API
|
||||
layout_data = fetch_layout()
|
||||
|
||||
# Fetch devices from API (now includes features)
|
||||
api_devices = fetch_devices()
|
||||
|
||||
# Create device lookup by device_id
|
||||
device_map = {d["device_id"]: d for d in api_devices}
|
||||
|
||||
# Build rooms with merged device data
|
||||
rooms = []
|
||||
for room in layout_data.get("rooms", []):
|
||||
devices = []
|
||||
for tile in room.get("devices", []):
|
||||
# Merge tile data with API device data
|
||||
device_data = {
|
||||
"device_id": tile["device_id"],
|
||||
"title": tile["title"],
|
||||
"icon": tile["icon"],
|
||||
"rank": tile["rank"],
|
||||
}
|
||||
|
||||
# Add type, name, and features from API if available
|
||||
if tile["device_id"] in device_map:
|
||||
api_device = device_map[tile["device_id"]]
|
||||
device_data["type"] = api_device.get("type")
|
||||
device_data["name"] = api_device.get("name")
|
||||
device_data["features"] = api_device.get("features", {})
|
||||
else:
|
||||
device_data["features"] = {}
|
||||
|
||||
devices.append(device_data)
|
||||
|
||||
# Sort devices by rank (ascending)
|
||||
devices.sort(key=lambda d: d["rank"])
|
||||
|
||||
rooms.append({
|
||||
"name": room["name"],
|
||||
"devices": devices
|
||||
})
|
||||
|
||||
logger.info(f"Rendering dashboard with {len(rooms)} rooms")
|
||||
|
||||
return templates.TemplateResponse("dashboard.html", {
|
||||
"request": request,
|
||||
"rooms": rooms
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error rendering dashboard: {e}", exc_info=True)
|
||||
# Fallback to empty dashboard
|
||||
return templates.TemplateResponse("dashboard.html", {
|
||||
"request": request,
|
||||
"rooms": []
|
||||
})
|
||||
|
||||
|
||||
def main() -> None:
|
||||
|
||||
Reference in New Issue
Block a user