diff --git a/web_server.py b/web_server.py new file mode 100644 index 0000000..092edc1 --- /dev/null +++ b/web_server.py @@ -0,0 +1,296 @@ +import asyncio +from contextlib import asynccontextmanager +from fastapi import FastAPI +from fastapi.responses import HTMLResponse, JSONResponse +from pydantic import BaseModel + +import wireclaw_core + + +@asynccontextmanager +async def lifespan(app: FastAPI): + await wireclaw_core.init() + yield + + +app = FastAPI(lifespan=lifespan) + + +async def process(text: str) -> str: + """Point d'entrée générique : texte libre → commande interprétée → exécutée.""" + cmd = await wireclaw_core.interpret_command(text) + return await wireclaw_core.execute_command(wireclaw_core.drone, cmd) + + +class CommandRequest(BaseModel): + text: str + + +@app.post("/command") +async def command(req: CommandRequest): + response = await process(req.text) + return {"response": response} + + +@app.get("/status") +async def status(): + await wireclaw_core.refresh_position(wireclaw_core.drone) + async for bat in wireclaw_core.drone.telemetry.battery(): + raw = bat.remaining_percent + pct = abs(raw) * 100 if abs(raw) <= 1 else abs(raw) + break + async for fm in wireclaw_core.drone.telemetry.flight_mode(): + mode = str(fm) + break + return { + "lat": wireclaw_core.current_pos["lat"], + "lon": wireclaw_core.current_pos["lon"], + "alt": round(wireclaw_core.current_pos["alt"], 2), + "abs_alt": round(wireclaw_core.current_pos["abs_alt"], 2), + "battery": round(pct, 1), + "mode": mode, + "armed": wireclaw_core.drone_armed, + } + + +@app.get("/") +async def index(): + return HTMLResponse(HTML) + + +HTML = """ + +
+ + +