Environment-aware drone mission monitoring platform: real-time telemetry over WebSocket, OpenWeather integration, effective speed correction, and AI-powered mission navigation with closing reports.
- Tech Stack
- Physical Structure
- Local Development
- Environment Variables
- API Reference
- Data Models
- Dependency Graph
| Layer | Technologies |
|---|---|
| Frontend | React 18, TypeScript, Vite, Tailwind CSS, Google Maps JavaScript API, TanStack Query, Zustand, Radix UI, Lucide |
| Backend | FastAPI, SQLAlchemy 2 (async), PostgreSQL (e.g. Neon), Uvicorn |
| Realtime | WebSocket (/ws/telemetry) for live telemetry push |
| External | OpenWeather API (wind), LangChain + OpenAI (reports & diagnosis), Google Maps Elevation API (optional) |
InsightAero/
├── README.md
├── dev.sh # One-shot script to run backend + frontend
├── .vscode/
│ └── settings.json
├── frontend/
│ ├── package.json
│ ├── vite.config.ts
│ ├── tsconfig.json
│ ├── index.html
│ ├── .env.example
│ ├── public/
│ │ ├── favicon.svg
│ │ ├── drone-marker.svg
│ │ └── map-marker-flag-icon.svg
│ └── src/
│ ├── main.tsx
│ ├── App.tsx
│ ├── index.css
│ ├── api/
│ │ ├── client.ts
│ │ ├── drones.ts
│ │ ├── tasks.ts
│ │ ├── simulation.ts
│ │ ├── flightSessions.ts
│ │ └── diagnose.ts
│ ├── components/
│ │ ├── GoogleMapView.tsx
│ │ ├── TelemetryHUD.tsx
│ │ ├── AIDiagnosticPanel.tsx
│ │ ├── TaskCreateForm.tsx
│ │ ├── MyDronesList.tsx
│ │ ├── FlightSessionsList.tsx
│ │ ├── TaskList.tsx
│ │ ├── TaskDetailDialog.tsx
│ │ ├── WeatherControls.tsx
│ │ ├── DestinationAddressInput.tsx
│ │ ├── AIFloatingNavigator.tsx
│ │ └── ui/ # dialog, alert-dialog, button, tooltip, slider, card, scroll-area
│ ├── contexts/
│ │ ├── ThemeContext.tsx
│ │ └── themeStorage.ts
│ ├── hooks/
│ │ ├── useDroneMap.ts
│ │ ├── useDrones.ts
│ │ ├── useTasks.ts
│ │ ├── useTelemetry.ts
│ │ └── useUserLocation.ts
│ ├── pages/
│ │ ├── Index.tsx
│ │ └── NotFound.tsx
│ └── stores/
│ ├── telemetryStore.ts
│ └── uiStore.ts
└── backend/
├── requirements.txt
├── requirements-dev.txt
├── .env.example
└── app/
├── main.py
├── config.py
├── database.py
├── models.py
├── monitoring.py
├── api/
│ ├── __init__.py
│ ├── drones.py
│ ├── tasks.py
│ ├── simulation.py
│ ├── flight_sessions.py
│ ├── diagnose.py
│ └── websocket.py
├── schemas/
│ ├── __init__.py
│ ├── common.py
│ ├── drone.py
│ ├── task.py
│ ├── simulation.py
│ └── diagnose.py
├── services/
│ ├── simulator.py
│ ├── ws_manager.py
│ ├── telemetry_writer.py
│ ├── task_handlers.py
│ ├── diagnosis_service.py
│ ├── env_diagnosis.py
│ ├── env_tools.py
│ ├── ai_report.py
│ ├── battery_planning.py
│ ├── wind_compensation.py
│ ├── task_report.py
│ └── (elevation, weather, run_state)
└── prompts/
├── __init__.py
└── diagnosis.txt
Start the backend first, then the frontend. The frontend uses Vite’s proxy to /api and /ws so requests go to the backend on port 8000.
cd backend
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# Edit .env: set DATABASE_URL (PostgreSQL; use postgresql+asyncpg://... for async),
# OPENWEATHER_API_KEY, OPENAI_API_KEY (optional)
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000cd frontend
npm install
cp .env.example .env.local
# Set VITE_GOOGLE_MAPS_API_KEY (required for map display)
npm run devOpen http://localhost:5173. Use “Start mission” to connect to the backend WebSocket and see live trajectory and weather.
If you see [vite] http proxy error or ECONNREFUSED, the backend is not running on port 8000.
From the project root (after backend/.venv and frontend/node_modules are set up):
./dev.shThis starts the backend in the background and the frontend in the foreground; Ctrl+C stops both.
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string (e.g. Neon). Use postgresql+asyncpg://user:password@host/dbname?sslmode=require for async. |
OPENWEATHER_API_KEY |
No | OpenWeather API key for wind speed/direction. |
OPENAI_API_KEY |
No | Used by LangChain for mission diagnosis and closing reports. |
GOOGLE_MAPS_API_KEY |
No | Backend env diagnosis (Elevation API); enable in Cloud Console if used. |
CORS_ORIGINS |
No | Comma-separated origins (e.g. http://localhost:5173). Empty ⇒ * and no credentials. |
DB_USE_SSL |
No | true / false; use true for Neon, false for local Postgres. |
SIM_LAT, SIM_LNG |
No | Simulation origin (default: Taipei). |
| Variable | Required | Description |
|---|---|---|
VITE_GOOGLE_MAPS_API_KEY |
Yes | Google Maps JavaScript API key (map won’t load without it). |
VITE_API_URL |
No | Backend base URL; dev defaults to Vite proxy. Set for production so API calls hit the correct host. |
VITE_WS_BASE_URL |
No | WebSocket URL; derived from VITE_API_URL if unset. |
| Method | Path | Description |
|---|---|---|
| GET | /health |
Health check. |
| Simulation | ||
| POST | /api/simulation/start |
Start simulation and begin telemetry push. |
| POST | /api/simulation/stop |
Stop simulation. |
| POST | /api/simulation/pause |
Pause simulation. |
| POST | /api/simulation/resume |
Resume simulation. |
| WebSocket | ||
| WS | /ws/telemetry |
Real-time telemetry stream. |
| Drones | ||
| GET | /api/drones |
List drones. |
| POST | /api/drones |
Create drone. |
| DELETE | /api/drones/{drone_id} |
Delete drone. |
| Tasks | ||
| GET | /api/tasks |
List tasks. |
| POST | /api/tasks |
Create task. |
| GET | /api/tasks/{task_id} |
Get task. |
| GET | /api/tasks/{task_id}/report |
Get task report. |
| POST | /api/tasks/{task_id}/start |
Start task. |
| POST | /api/tasks/{task_id}/pause |
Pause task. |
| POST | /api/tasks/{task_id}/resume |
Resume task. |
| POST | /api/tasks/{task_id}/cancel |
Cancel task. |
| DELETE | /api/tasks/{task_id} |
Delete task. |
| Flight sessions | ||
| GET | /api/flight-sessions |
List flight sessions. |
| GET | /api/flight-sessions/{session_id}/telemetry |
Get session telemetry. |
| POST | /api/flight-sessions/{session_id}/report |
Generate session report. |
| POST | /api/flight-sessions/{session_id}/diagnose |
Run diagnosis for session. |
| AI / diagnosis | ||
| POST | /api/plan-mission |
Plan mission (battery/path analysis). |
| POST | /api/diagnose |
Diagnose from telemetry payload. |
- Drone:
id,name,base_speed_m_min,status,last_lat,last_lng - FlightSession:
start_time,end_time,weather_snapshot, linked toDrone - Task:
name,status, with TaskAssignment (drone, route, status) and optional TaskReport - Telemetry:
lat,lng,alt,speed,heading,battery,wind_speed,wind_deg,effective_speed_m_min
flowchart LR
subgraph Frontend["Frontend (Vite :5173)"]
UI[Pages & Components]
API[api/client + modules]
WS[WebSocket /ws/telemetry]
end
subgraph Backend["Backend (FastAPI :8000)"]
Routes[API Routes]
DB[(PostgreSQL)]
Sim[Simulator]
Ext[OpenWeather / OpenAI / Elevation]
end
UI --> API
UI --> WS
API --> Routes
WS --> Routes
Routes --> DB
Routes --> Sim
Routes --> Ext
flowchart TB
subgraph Entry
main[main.tsx]
App[App.tsx]
end
subgraph Providers
Theme[ThemeContext]
Query[QueryClient]
Router[BrowserRouter]
Tooltip[TooltipProvider]
end
subgraph Pages
Index[Index]
NotFound[NotFound]
end
subgraph Features
Map[GoogleMapView]
HUD[TelemetryHUD]
AI[AIDiagnosticPanel]
Tasks[TaskList / TaskCreateForm]
Drones[MyDronesList]
Sessions[FlightSessionsList]
end
subgraph Data
hooks[useDrones, useTasks, useTelemetry, useDroneMap]
stores[telemetryStore, uiStore]
api[drones, tasks, simulation, flightSessions, diagnose]
end
main --> App
App --> Theme
App --> Query
App --> Router
App --> Tooltip
Router --> Index
Index --> Map
Index --> HUD
Index --> AI
Index --> Tasks
Index --> Drones
Index --> Sessions
Features --> hooks
Features --> stores
hooks --> api
api --> client[api/client]
flowchart TB
main[main.py]
main --> CORS[CORSMiddleware]
main --> drones_router[drones]
main --> tasks_router[tasks]
main --> sim_router[simulation]
main --> fs_router[flight_sessions]
main --> diag_router[diagnose]
main --> ws_router[websocket]
drones_router --> get_db[database]
drones_router --> models[models]
tasks_router --> get_db
tasks_router --> models
tasks_router --> task_handlers[task_handlers]
tasks_router --> simulator[simulator]
sim_router --> get_db
sim_router --> simulator
sim_router --> task_handlers
fs_router --> get_db
fs_router --> ai_report[ai_report]
fs_router --> env_diagnosis[env_diagnosis]
diag_router --> battery_planning[battery_planning]
diag_router --> env_diagnosis
diag_router --> weather[weather]
diag_router --> elevation[elevation]
ws_router --> simulator
ws_router --> ws_manager[ws_manager]
get_db --> DB[(PostgreSQL)]
simulator --> telemetry_writer[telemetry_writer]
simulator --> wind_compensation[wind_compensation]
env_diagnosis --> diagnosis_service[diagnosis_service]
env_diagnosis --> OpenWeather[OpenWeather API]
diagnosis_service --> LangChain[LangChain / OpenAI]
ai_report --> LangChain
elevation --> GoogleElevation[Google Elevation API]
| Frontend (npm) | Purpose |
|---|---|
| react, react-dom | UI |
| react-router-dom | Routing |
| @tanstack/react-query | Server state & caching |
| zustand | Client state (telemetry, UI) |
| @googlemaps/js-api-loader | Map |
| @radix-ui/* | Accessible primitives |
| tailwindcss, tailwind-merge, clsx, cva | Styling |
| lucide-react | Icons |
| Backend (pip) | Purpose |
|---|---|
| fastapi, uvicorn | API server |
| sqlalchemy, asyncpg | Async PostgreSQL |
| python-dotenv | Config |
| httpx | HTTP client (e.g. OpenWeather) |
| websockets | WebSocket support |
| langchain-openai, openai | AI reports & diagnosis |
The UI uses a dark theme with Orbitron / JetBrains Mono fonts, cyan accents, and a grid background, aligned with the reference aerosim-dashboard layout: map, HUD, weather controls, and AI diagnostic panel.