Real-time LoRa sensor mesh monitoring dashboard with LLM-powered anomaly detection.
Sensors push telemetry (temperature, humidity, pressure, battery, RSSI) via HTTP or raw LoRa payloads. The backend detects anomalies using statistical thresholds and then uses Claude to analyze each anomaly in natural language. A Next.js dashboard shows live sensor status and an anomaly feed via WebSocket.
LoRa Sensors → Gateway → POST /api/v1/readings
│
├── Store in SQLite
├── Broadcast via WebSocket
└── Anomaly Detection
│
├── Statistical thresholds
└── Claude LLM analysis
│
▼
Next.js Dashboard (real-time)
Backend: FastAPI, SQLAlchemy, SQLite, Anthropic Claude, WebSocket Frontend: Next.js 14, TypeScript, TailwindCSS Infra: Docker Compose
# Backend
cd backend
cp .env.example .env # add your Anthropic key
pip install -e .
uvicorn lora_dashboard.api.app:app --reload
# Frontend (separate terminal)
cd frontend
npm install
npm run devPOST /api/v1/readings— structured sensor readingPOST /api/v1/readings/raw— raw LoRa payload (JSON or CSV)
GET /api/v1/sensors— list all sensorsGET /api/v1/sensors/{id}— sensor detail with 24h statsGET /api/v1/sensors/{id}/readings— recent readingsGET /api/v1/anomalies— list anomalies with LLM analysis
WS /ws— WebSocket for live readings and anomaly alerts
The system detects:
- Temperature spikes/drops — deviation from 24h mean exceeding threshold
- Humidity anomalies — same approach
- Low battery — warning at 20%, critical at 10%
- Weak signal — RSSI below -100 dBm
Each anomaly is analyzed by Claude to provide context on likely cause and recommended action.
# Send a reading
curl -X POST "http://localhost:8000/api/v1/readings?sensor_id=garage-01&temperature=22.5&humidity=55&battery=87&rssi=-65"
# Send a raw LoRa payload
curl -X POST 'http://localhost:8000/api/v1/readings/raw?sensor_id=garage-01&payload={"temp":22.5,"hum":55}'cd backend
pip install -e ".[dev]"
pytest tests/ -v
ruff check src/