docs: add README with map/identification screenshots and pipeline diagram
Hero screenshot of the live Leaflet device map plus a marker popup showing an auto-identified device with confidence, and a Mermaid diagram of the parse -> category-route -> match -> map/export pipeline. Documents simple-mode run steps, API surface, and honest Phase-0 accuracy caveats. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
# GigLez — Wigle for Sub-GHz IoT
|
||||
|
||||
**A crowdsourced map of Sub-GHz RF devices.** Upload a Flipper Zero `.sub` capture with GPS,
|
||||
GigLez parses the signal, identifies the device by protocol signature, and pins it on an
|
||||
interactive map — building an open dataset of the 300–928 MHz IoT world (garage doors,
|
||||
doorbells, weather sensors, TPMS, remotes, and more).
|
||||
|
||||

|
||||
|
||||
Click any marker to see the automatically-identified device and match confidence:
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## Why
|
||||
|
||||
Wigle.net mapped the WiFi/Bluetooth/cellular world. Almost nobody has done the same for
|
||||
**Sub-GHz RF** — the unlicensed ISM bands where garage remotes, alarm sensors, tire-pressure
|
||||
monitors and cheap IoT gadgets chatter. GigLez collects those captures from *any* device
|
||||
(Flipper Zero, LilyGo, RTL-SDR, HackRF — anything that emits `.sub`), identifies them, and
|
||||
turns the aggregate into a labeled dataset for RF SIGINT research and ML training.
|
||||
|
||||
## How it works
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[".sub capture<br/>+ GPS"] --> B["Parser<br/>freq · preset · timing"]
|
||||
B --> C["Category Router<br/>band + timing-ratio + pulse-count"]
|
||||
C --> D["Protocol DB match<br/>+ confidence calibration"]
|
||||
D --> E["GPS resolve<br/>filename / manifest"]
|
||||
E --> F["Store"]
|
||||
F --> G["Leaflet map"]
|
||||
F --> H["Dataset export<br/>jsonl · csv · geojson"]
|
||||
```
|
||||
|
||||
The identifier first **routes** a capture to a device category using frequency band, pulse
|
||||
timing ratios and pulse counts, then scores it only against protocols in that category and
|
||||
calibrates the confidence (spread + category-mismatch penalties). This routing step is what
|
||||
lifts identification accuracy over naive whole-database matching.
|
||||
|
||||
## Features
|
||||
|
||||
- **Device-agnostic upload** — drag-and-drop `.sub` files; GPS from the filename or a manifest
|
||||
- **Automatic identification** — category routing → protocol-signature matching → confidence score
|
||||
- **Interactive map** — Leaflet with marker clustering, frequency-band color coding, and a heatmap view
|
||||
- **Search & filter** — by frequency, protocol, and geographic radius/bounding box
|
||||
- **Dataset export** — stream the labeled corpus as JSONL, CSV, or GeoJSON for ML training
|
||||
- **Stats dashboard** — total captures, unique devices, geographic coverage
|
||||
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
# install deps into a venv
|
||||
python3 -m venv venv && source venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
|
||||
# run the app (simple mode — JSON-backed, no database required)
|
||||
./start_web.sh
|
||||
# or explicitly:
|
||||
python3 -m uvicorn src.api.main_simple:app --host 0.0.0.0 --port 8000 --reload
|
||||
```
|
||||
|
||||
Then open **http://localhost:8000** for the map UI (`/docs` for the OpenAPI reference).
|
||||
|
||||
> **Modes.** `main_simple.py` is the live app and needs no database — captures persist to a
|
||||
> local JSON store, which is the fastest way to try GigLez. A full SQLAlchemy ORM path
|
||||
> (PostgreSQL + PostGIS in production, SQLite in dev via `DATABASE_URL=sqlite:///./giglez.db`)
|
||||
> also exists for scaled deployments.
|
||||
|
||||
## API
|
||||
|
||||
| Method | Endpoint | Purpose |
|
||||
|--------|----------|---------|
|
||||
| `POST` | `/api/v1/captures/upload` | Upload `.sub` files + GPS manifest |
|
||||
| `GET` | `/api/v1/query/captures` | List stored captures |
|
||||
| `GET` | `/api/v1/captures/{id}` | Capture detail |
|
||||
| `GET` | `/api/v1/stats/summary` | Platform statistics |
|
||||
| `GET` | `/api/v1/export?format=jsonl\|csv\|geojson` | Export the labeled dataset |
|
||||
| `GET` | `/health` | Health check |
|
||||
|
||||
## Supported formats
|
||||
|
||||
Flipper Zero `.sub` — both decoded key files (`Protocol` / `Bit` / `Key`) and RAW pulse
|
||||
captures (`RAW_Data` timing arrays). `.fff` and PCAP ingest are on the roadmap.
|
||||
|
||||
## Accuracy status
|
||||
|
||||
Identification is at **Phase 0** — category routing plus a calibrated confidence model.
|
||||
The current gate benchmark (`scripts/benchmark_phase0.py`) reports **~67% top-3** category
|
||||
accuracy, but note this runs on **synthetic `.sub` files generated from the protocol database
|
||||
itself**, so treat it as an *upper bound*, not a real-world number. Real-world validation
|
||||
against field Flipper captures, and a hybrid heuristic + 1D-CNN ML ensemble, are the next
|
||||
milestones.
|
||||
|
||||
## Tech stack
|
||||
|
||||
Python · FastAPI · Leaflet.js · SQLAlchemy (PostgreSQL/PostGIS · SQLite) · Flipper `.sub` parsing
|
||||
|
||||
## Roadmap
|
||||
|
||||
- [x] `.sub` parser + GPS validation
|
||||
- [x] Category-routed device identification (Phase 0)
|
||||
- [x] Web UI (map / upload / search / stats) + dataset export
|
||||
- [ ] Real-world accuracy validation on field captures
|
||||
- [ ] ML ensemble (heuristic + 1D CNN on raw pulses + statistical features)
|
||||
- [ ] Community verification, accounts, leaderboard
|
||||
- [ ] Docker deployment; 2.4/5 GHz (PCAP + OUI) as a later phase
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.6 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.8 MiB |
Reference in New Issue
Block a user