feat: FastAPI app with REST API routes and WebSocket endpoint
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
84
src/mqtt_home/main.py
Normal file
84
src/mqtt_home/main.py
Normal file
@@ -0,0 +1,84 @@
|
||||
import asyncio
|
||||
import logging
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
from mqtt_home.config import get_settings
|
||||
from mqtt_home.database import init_db, get_session_factory, Base
|
||||
from mqtt_home.mqtt_client import MqttClient
|
||||
from mqtt_home.emqx_api import EmqxApiClient
|
||||
from mqtt_home.discovery import handle_discovery_message
|
||||
from mqtt_home.device_registry import handle_state_update
|
||||
from mqtt_home.api import api_router
|
||||
from mqtt_home.ws import websocket_endpoint, broadcast_device_update
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
settings = get_settings()
|
||||
|
||||
await init_db()
|
||||
logger.info("Database initialized")
|
||||
|
||||
emqx = EmqxApiClient(settings)
|
||||
app.state.emqx_client = emqx
|
||||
logger.info("EMQX API client initialized")
|
||||
|
||||
mqtt = MqttClient(settings)
|
||||
app.state.mqtt_client = mqtt
|
||||
|
||||
session_factory = get_session_factory()
|
||||
|
||||
async def on_discovery(topic: str, payload: str):
|
||||
async with session_factory() as db:
|
||||
await handle_discovery_message(topic, payload, db, mqtt)
|
||||
|
||||
async def on_state(topic: str, payload: str):
|
||||
async with session_factory() as db:
|
||||
device = await handle_state_update(db, topic, payload)
|
||||
if device:
|
||||
await broadcast_device_update(device.id, {
|
||||
"state": device.state,
|
||||
"is_online": device.is_online,
|
||||
"last_seen": device.last_seen.isoformat() if device.last_seen else None,
|
||||
})
|
||||
|
||||
mqtt.on_message("homeassistant/#", on_discovery)
|
||||
mqtt.on_message("home/#", on_state)
|
||||
|
||||
await mqtt.start()
|
||||
logger.info("MQTT client started")
|
||||
|
||||
yield
|
||||
|
||||
await mqtt.stop()
|
||||
await emqx.close()
|
||||
logger.info("Shutdown complete")
|
||||
|
||||
|
||||
app = FastAPI(title="MQTT Home", version="0.1.0", lifespan=lifespan)
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
app.include_router(api_router)
|
||||
app.websocket("/ws/devices")(websocket_endpoint)
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
async def health():
|
||||
mqtt = getattr(app.state, "mqtt_client", None)
|
||||
return {
|
||||
"status": "ok",
|
||||
"mqtt_connected": mqtt.is_connected if mqtt else False,
|
||||
}
|
||||
Reference in New Issue
Block a user