-
Notifications
You must be signed in to change notification settings - Fork 2
Home
Welcome to the official technical documentation for the QuakeGuard project (Release v1.1.0).
- System Architecture & Overview
- Hardware & Edge Computing
- Cryptographic Security & Provisioning
- Data Plane & Message Broker
- Backend Services & Event Processing
- Mobile Client & Live Telemetry
- Deployment & Operations Guide
QuakeGuard is a distributed, high-throughput backend system designed for the real-time ingestion, cryptographic validation, and processing of seismic data from IoT devices. It serves as the core infrastructure for an Earthquake Early Warning (EEW) system. The architecture is explicitly designed to handle high-concurrency event firehosing during seismic swarms while maintaining strict security boundaries.
The infrastructure is decoupled into three primary tiers:
- Edge Layer (IoT): Composed of ESP32-C3 SuperMini microcontrollers interfaced with ADXL345 digital accelerometers. These nodes execute on-device Digital Signal Processing (DSP) using the STA/LTA algorithm.
-
Core Backend & Processing: A polyglot backend architecture utilizing FastAPI (Python) as the API gateway. Validated data is asynchronously offloaded to a Redis message queue (
seismic_events) and consumed by a background worker. - Client Presentation Layer: A React Native (Expo) mobile application providing users with real-time seismograph telemetry and instantaneous critical event notifications.
Following the v1.1.0 cloud migration, the architecture strictly separates pipelines:
-
Data Plane (Telemetry): Flows exclusively through a HiveMQ Cloud Serverless broker on port 8883 (authenticated and TLS-encrypted). A Python MQTT bridge (
mqtt_subscriber.py) forwards payloads to the internal FastAPI ingestion pipeline. - Control Plane (Provisioning & Management): Device onboarding, cryptographic handshakes, and REST retrieval operations are routed through an ngrok HTTPS tunnel, directly exposing FastAPI endpoints.
The edge layer operates on resource-constrained microcontrollers, specifically the ESP32-C3 SuperMini (RISC-V architecture).
Due to the specific physical layout, the I2C bus is software-mapped to non-standard GPIO pins:
- SDA (Data): GPIO 7 (requires internal pull-up).
- SCL (Clock): GPIO 8 (requires internal pull-up).
- Power: The ADXL345 is powered strictly via the 3.3V rail.
The sensor operates at a 100Hz sampling rate (ADXL345_DATARATE_100_HZ) with a measurement range of ±16G.
-
High-Pass Filter (HPF): A digital filter (
HPF_ALPHA = 0.9f) isolates dynamic vibration data by subtracting the static DC component (Earth's gravity). - Noise Gate: Micro-vibrations below the empirical threshold of 0.04G are clamped to zero to prevent false positives from electrical noise.
-
Dropout Protection: The firmware automatically drops frames reporting near-zero absolute acceleration (< 2.0
$m/s^2$ prior to filtering), mitigating corrupted readings from I2C disconnects.
The implementation utilizes a custom, memory-efficient RingBuffer template class in C++ to maintain rolling sums for
- Short-Term Window (STA): 100 samples (1 second).
- Long-Term Window (LTA): 1000 samples (10 seconds).
-
Trigger Condition: An earthquake is registered when the STA/LTA ratio exceeds
1.8f, provided the STA absolute value is above the noise floor.
QuakeGuard implements a Zero-Trust security model for its IoT edge nodes.
Upon its first boot, the ESP32-C3 uses mbedtls to generate a unique ECDSA key pair using the NIST P-256 curve (secp256r1).
- Private Key: Stored permanently in Non-Volatile Storage (NVS) to sign outgoing telemetry.
- Public Key: Extracted in DER format, acting as the unforgeable cryptographic identity of the sensor.
- The device sends a
POSTto/devices/registerwith itspublic_key_hex, MAC address, coordinates, andENROLLMENT_TOKEN. - The backend validates the token and uses PostGIS (
ST_Contains) to assign the sensor to the smallest containing geographic polygon. - A unique
sensor_idis returned and saved to NVS.
Telemetry payloads (value:timestamp) are hashed via SHA-256 and signed with the private key. The validate_iot_payload dependency pipeline enforces:
-
API Key Verification: Constant-time
hmac.compare_digestcheck. - Sensor Status: Verifies the sensor ID is active.
- Anti-Replay Protection: Rejects payloads older than a 300-second threshold.
-
Signature Verification: Uses the Python
cryptographylibrary to verify the ECDSA signature against the device's public key.
With v1.1.0, QuakeGuard migrated its Data Plane from HTTP/local MQTT to a robust cloud infrastructure.
- Encrypted Transport: Telemetry is transmitted over port 8883 using strict TLS.
-
Authentication: Requires explicit
MQTT_USERNAMEandMQTT_PASSWORD. -
Topic Topology: Anomalies are published to
quakeguard/telemetry.
The backend securely ingests data via mqtt_subscriber.py.
- Uses
paho.mqtt.clientwith secure TLS settings (client.tls_set). - Forwards payloads to the internal FastAPI ingestion endpoint (
/readings/) via HTTP POST. - Injects the
X-API-Keyheader, acting as a trusted proxy.
- Rate Limiting: Protects against DoS via a sliding-window rate limiter in Redis (50 req/s per IP).
-
Queue Offloading: Validated payloads are non-blockingly serialized and pushed to a Redis List (
seismic_events), returning a202 Acceptedimmediately.
A decoupled Python worker (worker.py) consumes the seismic_events queue via a blocking brpop.
- Shares a highly optimized SQLAlchemy connection pool targeting PostgreSQL/PostGIS.
- Evaluates the alarm logic within a single, atomic database transaction (
db.commit()).
The worker estimates physical magnitude based on a MyShake-style MEMS calibration approach:
Where K_CALIBRATION = 1.6), and B_OFFSET = 3.0).
-
Thresholding: Triggers an
Alertif the magnitude reaches or exceeds 4.5. -
Redis Deduplication: Uses an atomic check-and-set (
SET nx=True, ex=60) keyed byzone_idto enforce a 60-second cooldown per zone, preventing notification spam during a swarm. -
Outbox Pattern: Publishes the JSON payload to the
quake_alertsRedis Pub/Sub channel.
Built with React Native and Expo, the client serves as the primary EEW notification interface.
-
Connection: Maintains a persistent WebSocket to
/ws/alerts, authenticated viaMOBILE_WS_TOKENwith exponential backoff. -
Native Haptics & Notifications:
"CRITICAL"payloads trigger an SOS vibration pattern and schedule a high-priority system push notification (AndroidImportance.MAX).
- Data Fetching: Standard REST operations are managed by TanStack Query for automatic caching and background refetching.
-
Live Seismograph: Uses
victory-nativeto render a dynamic line chart of aggregated seismic activity. -
Geospatial Map:
react-native-mapsdisplays custom markers based on exact PostGIS coordinates, colored by active/offline status.
-
Alert Store:
useAlertStoremaintains a rolling history of the 10 most recent alerts. -
Offline Mode:
usePreferencesStorecontrols an "Offline Mode" that intentionally closes WebSockets and disables React Query polling to conserve battery.
This section outlines the procedures for provisioning the QuakeGuard infrastructure.
- Backend: Docker Engine & Docker Compose.
- Edge (IoT): VS Code + PlatformIO extension.
- Mobile: Node.js (v18+) & Expo Go app.
- Navigate to
backend/api. - Copy the environment variables:
cp .env.example .envand fill in your HiveMQ credentials. - Launch the stack:
docker compose up --build -d- Verify health at
http://localhost:8000/health.
- Navigate to
firmware/esp32_code. - Copy the config:
cp esp32_config.env.example esp32_config.env. - Update WiFi credentials,
SERVER_HOST, andENROLLMENT_TOKEN. - Flash via PlatformIO.
- Open Serial Monitor (115200 baud) to verify successful automated registration.
- Navigate to
mobile/and runnpm install. - Create a
.envfile mapping your backend secrets and IP:
EXPO_PUBLIC_IOT_API_KEY=your_secret_key
EXPO_PUBLIC_MOBILE_WS_TOKEN=your_ws_token
EXPO_PUBLIC_API_BASE_URL=http://YOUR_LOCAL_IP:8000- Run
npx expo startand scan the QR code with your smartphone.
Validate your infrastructure by simulating a 150-node seismic swarm:
cd backend/api
export API_URL="http://localhost:8000"
export NUM_SENSORS=150
python -m tests.stress_testA successful run ends with 🏆 SYSTEM CERTIFIED.