Full-Stack IoT Architecture for Real-Time Earthquake Detection
๐ Technical Specification: A comprehensive architecture whitepaper is available in the
docs/directory, compiled via Typst. For a browsable, topic-by-topic reference, check out the project Wiki.
QuakeGuard is a full-stack IoT architecture for real-time detection, analysis, and reporting of seismic events. The system transforms everyday household appliances โ washing machines, TVs, refrigerators โ into a distributed seismic sensor network, each node capable of detecting and reporting earthquake activity autonomously.
Intelligent edge sensors (ESP32-C3 + ADXL345) analyze vibrations locally using professional-grade algorithms and transmit cryptographically signed data to an asynchronous cloud backend. The backend is engineesred to handle the massive traffic spikes โ the Thundering Herd effect โ typical during widespread seismic events, ensuring reliable alarm delivery without bottlenecking. A React Native mobile app receives real-time haptic and visual alerts via WebSocket.
The QuakeGuard v2.0 fully assembled PCB, featuring the ESP32-C3 SuperMini, the ADXL345 accelerometer, and the u-blox GNSS module. For a complete list of required components, refer to the Bill of Materials (BOM) in the Wiki.
ESP32-C3 + ADXL345
โ
โ MQTT (signed payload)
โผ
MQTT Bridge โโโบ POST /readings/ โโโบ ECDSA Verification
โ
โผ
Redis Queue
โ
โผ
Background Worker โโโโโบโโโโโโโโโโโโโ
โ โ (Queue) โ AI Worker โ
โผ โผ โ (Ollama) โ
PostgreSQL Redis Pub/Sub โโโโโโโโโฌโโโโโโ
+ PostGIS โ
โผ
WebSocket Broadcast
โ
โผ
React Native Mobile App
(Haptic + Visual Alert)
The project follows Microservices and Event-Driven Design principles across three fully independent layers.
| Feature | Detail |
|---|---|
| Hardware | ESP32-C3 SuperMini + ADXL345 Accelerometer |
| Sampling Rate | 100 Hz |
| Detection Algorithm | STA/LTA (Short Term / Long Term Average) |
| Signal Processing | Digital High-Pass Filter (HPF) to remove gravity |
| Data Structure | Statically allocated Ring Buffers (RingBuffer<100> STA, RingBuffer<1000> LTA) |
| Security | ECDSA NIST256p cryptographic signing on every payload |
| Transmission | MQTT publish to quakeguard/telemetry |
| Provisioning | Automated device handshake on first boot via POST /devices/register |
| Secret Injection | Compile-time ENROLLMENT_TOKEN via PlatformIO pre-script + #error fail-fast |
| Feature | Detail |
|---|---|
| Framework | FastAPI (Python 3.11), fully async |
| Security | API Key auth, ECDSA signature verification, Anti-Replay (300s window) |
| Message Broker | Redis โ decouples ingestion from processing |
| Rate Limiting | Fixed-window 50 req/s per IP via Redis |
| Alert Engine | ML-like magnitude proxy (M = log10(PGA_calib) + b), threshold M โฅ 4.5 |
| Deduplication | Redis TTL cooldown lock per zone (60s), prevents alert storms |
| Persistence | PostgreSQL + PostGIS with recorded_at timestamps |
| Zone Assignment | Automatic via PostGIS ST_Contains spatial query, ordered by ST_Area ascending |
| Zone Seeding | 8 pre-populated global macro-regions + "Unknown Region" fallback |
| Observability | GET /health โ concurrent PostgreSQL + Redis ping |
| Secrets | Fail-fast RuntimeError on missing env vars at startup |
| MQTT Bridge | mqtt_subscriber.py โ forwards MQTT payloads to the secure HTTP pipeline |
| Edge AI | Asynchronous emergency report generation via local Ollama (Llama 3.2) |
| Feature | Detail |
|---|---|
| Framework | React Native (Expo) with TypeScript |
| Navigation | Expo Router โ 3-tab Bottom Navigator (Monitor, Sensors Map, Settings) |
| State Management | Zustand slices (usePreferencesStore, useAlertStore) |
| Server State | TanStack Query + Axios โ caching, background refetch, retry |
| Real-Time | WebSocket context with exponential backoff reconnection |
| Alert Delivery | SOS haptic vibration pattern + OS push notification via expo-notifications |
| Alert History | In-session feed of last 10 critical events |
| AI Report Banner | Inline AI-generated emergency report (summary + recommendations) for the latest alert, with "Report unavailable" badge on failures |
| Offline Mode | Toggle silences WebSocket, halts all TanStack Query polling |
| Notifications | notificationsEnabled toggle gates haptics and push notifications |
| Safe Areas | react-native-safe-area-context โ Dynamic Island and punch-hole compatible |
Data integrity is paramount in an emergency system. Every telemetry packet is cryptographically secured end-to-end.
ESP32 signs payload with ECDSA NIST256p (SHA256)
โ
Backend verifies signature against registered public key
โ
Timestamp validated within 300-second window (Anti-Replay)
โ
API Key checked on every request (X-API-Key header)
โ
Payload accepted โ Redis Queue
Threat model coverage:
- โ Man-in-the-Middle (MitM) โ ECDSA signature verification
- โ Spoofing โ public key registration + signature check
- โ Replay attacks โ 300-second timestamp window
- โ Brute force โ rate limiting 50 req/s per IP
- โ Unauthorized access โ API Key + enrollment token fail-fast
- Docker Desktop & Docker Compose
- PlatformIO (VS Code Extension)
- Node.js 18+ & Expo Go (mobile)
- A mobile hotspot or shared WiFi network for ESP32 + backend connectivity
cd backend
cp .env.example .envEdit .env and set the required secrets:
# --- Application Secrets ---
IOT_API_KEY=your_secret_key
MOBILE_WS_TOKEN=your_ws_token
ENROLLMENT_TOKEN=your_enrollment_token
# --- Database ---
POSTGRES_DB=quakeguard_db
POSTGRES_USER=developer
POSTGRES_PASSWORD=your_db_password
API_PORT=8000
# --- Cloud MQTT (HiveMQ) ---
MQTT_BROKER=your-cluster-id.s1.eu.hivemq.cloud
MQTT_PORT=8883
MQTT_USERNAME=your_mqtt_username
MQTT_PASSWORD=your_mqtt_password
# --- AI Emergency Reports (hybrid Edge AI architecture) ---
AI_REPORT_ENABLED=true
OLLAMA_HOST=http://127.0.0.1:11434
OLLAMA_MODEL=llama3.2:1b
โ ๏ธ The backend will refuse to start if any of these are missing โ this is intentional fail-fast behavior.
๐ก Edge AI Architecture (v2.0.0): To maximize hardware efficiency and avoid Docker's GPU passthrough overhead, QuakeGuard employs an industrial Hybrid Edge AI pattern (similar to NVIDIA Jetson or Tesla FSD architectures). The core AI inference engine (Ollama) runs bare-metal on the host Linux OS, while the application microservices run in Docker and communicate via
network_mode: "host".To enable on-premise AI reports:
- Install Ollama natively on your Linux host:
curl -fsSL https://ollama.com/install.sh | sh- Pull the model natively:
ollama pull llama3.2:1b- Start the Docker stack with the AI worker profile:
docker compose --profile ai up --build -dReports are generated entirely on your machine: telemetry never leaves the host.
cd backend
docker compose up --build -d| Endpoint | URL |
|---|---|
| API | http://localhost:8000 |
| Swagger UI | http://localhost:8000/docs |
| Health Check | http://localhost:8000/health |
cd firmware
cp esp32_config.env.example esp32_config.env
# Edit esp32_config.env with your network IP and ENROLLMENT_TOKENFlash via PlatformIO. On first boot the device will:
- Open a WiFi captive portal (
QuakeGuard-Setup) - Connect to your network
- Automatically register with the backend and receive a
sensor_id
๐ก If the sensor registers with
latitude=0.0, longitude=0.0it will be assigned to "Unknown Region". Hardcode your coordinates inmain.cppfor correct zone assignment until GPS integration is complete.
cd mobile
npm installUpdate constants/config.ts with your machine's local IP:
export const API_BASE_URL = "http://YOUR_LOCAL_IP:8000";Create .env in the mobile root:
EXPO_PUBLIC_IOT_API_KEY=your_secret_key
EXPO_PUBLIC_MOBILE_WS_TOKEN=your_ws_tokennpx expo startScan the QR code with Expo Go. Ensure your phone is on the same WiFi network as the backend machine.
Validates the full pipeline: ingestion โ Redis โ worker โ PostGIS โ WebSocket alerts.
cd backend
export API_URL="http://localhost:8000"
export NUM_SENSORS=150
export CONCURRENCY_LIMIT=50
python -m tests.stress_testThree phases:
| Phase | What it tests |
|---|---|
| ๐ฅ Phase 1 โ Firehose | 150 concurrent sensors, rate limiter validation |
| โ๏ธ Phase 2 โ Security | Bad signature blocked (401), Replay attack blocked (403) |
| ๐ Phase 3 โ E2E | DB persistence verified via polling GET /sensors/{id}/statistics |
A successful run ends with ๐ SYSTEM CERTIFIED.
Trigger a simulated earthquake instantly from Swagger UI without running the stress test:
POST /demo/trigger-earthquake
Default payload (works with empty {}):
{
"zone_id": 1,
"magnitude": 7.5,
"message": "Simulated Critical Event"
}This publishes directly to the Redis quake_alerts channel, bypassing the IoT pipeline entirely and triggering the mobile app alert UI within milliseconds.
The database is pre-seeded with 8 global macro-regions. Sensors are automatically assigned to the correct zone via PostGIS spatial query at registration time.
| Zone | Coverage |
|---|---|
| Italy - North | Lombardy, Veneto, Piedmont |
| Italy - Center | Tuscany, Lazio, Umbria |
| Italy - South & Islands | Campania, Sicily, Sardinia |
| Western Europe | France, Spain, Germany, UK |
| North America | USA, Canada, Mexico |
| South America | Brazil, Argentina, Chile |
| East Asia | China, Japan, India |
| Unknown Region | Fallback for unmapped coordinates |
| Workflow | Trigger | Checks |
|---|---|---|
backend-ci.yml |
backend/** |
Bandit, Safety, stress test |
frontend-ci.yml |
mobile/** |
ESLint, npm audit |
iot-ci.yml |
firmware/** |
PlatformIO compilation |
pr-lint.yml |
All PRs | Semantic PR title (type(scope): message) |
devops-ci.yml |
.github/workflows/** |
Actionlint workflow validation |
QuakeGuard/
โโโ backend/
โ โโโ src/
โ โ โโโ main.py # FastAPI gateway + REST endpoints
โ โ โโโ security.py # ECDSA, API Key, Anti-Replay
โ โ โโโ worker.py # Redis consumer + magnitude + alert engine + AI enqueue
โ โ โโโ ai_report_worker.py # Dedicated AI report consumer (Ollama + state machine)
โ โ โโโ ollama_client.py # Deterministic LLM client (anti-hallucination)
โ โ โโโ mqtt_subscriber.py # MQTT to HTTP bridge
โ โ โโโ seed.py # Geographic zone seeder
โ โ โโโ models.py # SQLAlchemy ORM models (+ EmergencyReport)
โ โ โโโ schemas.py # Pydantic request/response schemas
โ โ โโโ database.py # DB engine and session factory
โ โโโ tests/
โ โ โโโ stress_test.py # Critical E2E stress test suite
โ โ โโโ unit/ # Unit tests (worker, ollama client, AI worker, models, ...)
โ โโโ init-scripts/
โ โ โโโ ollama-entrypoint.sh # Auto-pulls the Ollama model on startup
โ โโโ build.ps1 # Automatic container publish
โ โโโ docker-compose.yml
โ โโโ Dockerfile
โ โโโ mosquitto.conf
โ โโโ requirements.txt # Python requirements for backend development
โ โโโ .env.example
โโโ mobile/
โ โโโ app/ # Expo Router screens
โ โ โโโ (tabs)/
โ โ โโโ index.tsx # Monitor / Dashboard
โ โ โโโ map.tsx # Sensor Network Map
โ โ โโโ settings.tsx # User Preferences
โ โโโ api/ # Axios client + TanStack Query hooks
โ โโโ components/ # Shared UI components
โ โโโ store/ # Zustand state slices
โ โโโ context/
โ โ โโโ WebSocketContext.tsx # Real-time alert context
โ โโโ constants/
โ โโโ config.ts # Centralized configuration
โโโ firmware/
โ โโโ src/
โ โ โโโ main.cpp # FreeRTOS tasks, STA/LTA, MQTT, provisioning
โ โ โโโ DetectionCore.h # Pure-C++ STA/LTA core (shared firmware/host, R1)
โ โ โโโ RingBuffer.h # Statically allocated circular buffer
โ โโโ tools/
โ โ โโโ detect_cli.cpp # Native host CLI (SIL replay, same core)
โ โโโ test/ # Test scripts to insert into the ESP32
โ โโโ key-generator/ # ECDSA key generator for backend testing
โ โโโ esp32_config.env.example
โ โโโ extra_script.py # ENV variables injector
โ โโโ platformio.ini
โโโ research/ # SIL validation (ROADMAP R1)
โ โโโ fetch_itaca.py # ITACA download (graceful degradation) / synthetic fallback
โ โโโ synthetic.py # Realistic synthetic dataset generator
โ โโโ calibrate_io.py # Dataset layout I/O + path-injection guard
โ โโโ orchestrator.py # Compile & run the host C++ CLI (subprocess bridge)
โ โโโ metrics.py # Sensitivity, False-Alarm Rate, latency, ROC
โ โโโ calibrate.py # TRIGGER_RATIO x NOISE_FLOOR sweep (F1 maximization)
โ โโโ plot_roc.py # ROC curve figure for the paper
โ โโโ requirements.txt # matplotlib (optional, plotting)
โ โโโ README.md # Dataset layout, unit conversion, licensing policy
โโโ docs/ # Technical Documentation
โโโ main.typ # Typst Whitepaper Entrypoint
โโโ 01-architecture.typ # System Architecture & Overview
โโโ 02-hardware.typ # Hardware & Edge Computing (ESP32-C3)
โโโ 03-security.typ # Cryptographic Security & Provisioning
โโโ 04-broker.typ # Data Plane & Message Broker (MQTT)
โโโ 05-backend.typ # Backend Services & Event Processing
โโโ 06-mobile.typ # Mobile Client & Live Telemetry
โโโ 07-deployment.typ # Deployment & CI/CD
โโโ 08-ai.typ # AI Emergency Report Service (v1.2.0)
| Version | Focus |
|---|---|
| v1.0 | โ Released โ edge seismic detection on ESP32, local alerts |
| v1.1 | โ Released โ HiveMQ Cloud MQTT (TLS), ngrok HTTPS tunnel, security hardening |
| v1.2 | โ Released โ On-Premise AI Worker (Local Ollama / Llama 3.2) for privacy-preserving emergency reports |
| v1.2.1 | โ
Released โ Geo-Zoning & Cooldown Fragmentation โ geohash Redis zone index (FastAPI/PostGIS source of truth), per-area cooldown, GNSS-ready data model (Sensor.last_fix_at, Reading.lat/lon), per-zone live seismograph |
| v1.2.2 | โ Released โ Zero-Trust Serial Fallback โ signed telemetry over USB CDC (serial) when MQTT is unreachable |
| v2.0.0 | โ Released โ Triangulation (multi-node spatial correlation), Hybrid Network Architecture, Automated DevOps Orchestration (Ptyxis), Local Factory Provisioning, GNSS sync, NTP+PPS, ADXL calibration, and INGV FDSN SIL validation |
| v2.0.1 | โ
Released โ Documentation & Zenodo Sync: PDF/Wiki architectural coherence (Cloudflare, 300s anti-replay), CERN-OHL hardware licensing, SIL vs Firmware threshold clarification, and CITATION.cff bump |
| v2.1 | Data Dashboards โ Grafana dashboards for real-time visualization of seismic telemetry |
| v2.1.1 | Timeseries DB & Mobile Fix โ migration to TimescaleDB/InfluxDB; per-sensor chart isolation in React Native mobile |
| v2.2 | Heterogeneous Edge Intelligence โ hybrid Tier A (STA/LTA) + Tier B (quantized CNN) decision fusion |
| Future | Cloud IaC โ Kubernetes + Terraform auto-scaling platform (see ROADMAP.md) |
| Node | Focus |
|---|---|
| #Research | Parallel ongoing node โ SIL cross-validation: replay of the exact production C++ STA/LTA core (DetectionCore.h) on the host via the same C++ source, Python-only as orchestrator, ROC metrics + AI benchmarking (latency P50/P99, hallucination rate). R1 pipeline (core isolation, host CLI, orchestrator, metrics, calibration) implemented; see ROADMAP.md |
QuakeGuard's architecture and real-world applicability have been recognized in the following academic and industrial contexts:
- ๐ฅ 1st Place Overall - Institute Project Day (2025): Awarded best technical project out of ~20 prototypes across four engineering disciplines (Computer Science, Automation, Mechanics, Chemistry). The full-stack architecture was evaluated and awarded by an industrial jury featuring technical representatives from Siemens, ABB, SORINT.lab, SAME, Ferrero, and Confindustria.
- ๐ Academic Origin & Consultation: The system's conceptualization originated during the 2025 CQIIA-MatNet Summer School (Universitร di Bergamo). The distributed network logic and spatial deployment strategy were subsequently refined following technical consultations with Prof. F. Finazzi.
- ๐ GF Marilli Competition: [Currently competing - Pending evaluation].
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See the LICENSE file for details.
Developed by GiZano and riccardo0731
Open Source โ AGPL-3.0 License

