Skip to content

Latest commit

 

History

122 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DroneAware Node — Setup Guide

⚡ Get a node online in ~10–15 minutes → Start Here

Detections from nodes already running on the network:

DroneAware_Screenshot1

See drones flying near you in real time - most people never see Remote ID unless they build something like this.

Nodes are already running in the US, Germany, and Canada - and growing daily.

DroneAware Network is a community-built, open Remote ID detection network. The goal is to create a distributed, real-time view of drone activity with low-cost sensors - where the value isn't just the software, but the shared detection network everyone contributes to.

Run one command and start detecting drones around you, from a few hundred yards to miles away depending on your setup::

curl -fsSL https://github.com/fduflyer/DroneAware-Node-Releases/releases/latest/download/install.sh | sudo bash

No Linux experience needed — if you can plug in a USB device, you can run this.

Your new DroneAware node will listen for FAA-mandated Remote ID broadcasts from drones flying in your area and forward them to the DroneAware Network, where they appear on a live map at droneaware.io.

DroneAware_Screenshot2

Once connected, you'll also get real-time email alerts anytime your node(s) detect a drone. You can also go back and view all of your detections by date and time to watch a replay of their flight paths.

DroneAware Screenshot2


What You Need

Item Notes
Raspberry Pi 4 (1 GB or more) 2 GB+ recommended if running other software
MicroSD card (16 GB+, Class 10) Samsung Endurance or SanDisk High Endurance preferred
USB Bluetooth adapter Sena UD100 (newer variants with Bluetooth 4.0+ only) or any CSR/Cambridge Silicon Radio USB dongle. Older UD100 variants (G01, G02, G03 and similar) are Bluetooth Classic (BT 2.0/2.1) only and will not work. If unsure which version you have, the Pi's built-in Bluetooth works out of the box at shorter range.
WiFi adapter (required) Alfa AWUS036N (Ralink RT3070 chipset, 2.4 GHz)
5V/3A USB-C power supply Official Raspberry Pi PSU recommended
Ethernet cable or WiFi credentials For initial setup

Why a USB Bluetooth adapter? The Pi's built-in Bluetooth works, but its antenna is inside the case. A USB dongle with an external antenna has significantly better range. The Sena UD100 / CSR chipset is confirmed working and widely available for under $20.

Why the Alfa WiFi adapter? The Alfa AWUS036N supports monitor mode, which is required to capture Wi-Fi Remote ID beacon frames (the 802.11 transport used by many newer drones). The Pi's built-in WiFi cannot be put into monitor mode reliably.


How It Works

DroneAware nodes run two background services that continuously scan for drone Remote ID broadcasts:

BLE Feeder (droneaware-ble) Listens for Bluetooth Low Energy advertisements carrying Remote ID service data (UUID 0xFFFA, ASTM F3411). When a drone broadcast is detected, the raw 25-byte ODID message is decoded locally (drone ID, position, speed, operator location) and forwarded to the DroneAware server in batches.

WiFi Feeder (droneaware-wifi) Places the Alfa adapter into monitor mode and hops across 2.4 GHz channels (1–11) looking for 802.11 beacon frames carrying vendor-specific Remote ID payloads (OUI FA:0B:BC, ASTM F3411) and Wi-Fi NAN action frames (OUI 50:6F:9A). Detected payloads are forwarded to the server alongside MAC address and RSSI.

Data Flow

Drone (Remote ID broadcast)
  → Pi USB BT/WiFi adapter (raw capture)
    → ble_feeder / wifi_feeder (batch over HTTPS)
      → api.droneaware.io (decode + store)
        → droneaware.io (live map)

Both services start automatically at boot, restart on crash, and send a heartbeat to the server every 60 seconds so the dashboard shows the node as online. Detections are forwarded to the DroneAware server in real time and also written to a local ring buffer (/run/droneaware/detections.jsonl) stored in RAM — the last 60 minutes of detections are kept on the Pi and purged automatically. Nothing is written to the SD card.

What data is collected? Only data broadcast publicly by the drones themselves via FAA-mandated Remote ID transmissions. Remote ID is an open broadcast equivalent to a drone's tail number visible on a radar screen. No private communications, networks, or personal devices are accessed. Your node's GPS coordinates are stored on the DroneAware server to correctly place detections on the map.


Quick Start

Step 1 — Flash the SD Card

  1. Download Raspberry Pi Imager on your computer.
  2. Click Choose OS → Raspberry Pi OS (other) → Raspberry Pi OS Lite (64-bit).
  3. Click the gear icon (Advanced Options) and configure:
    • Set hostname: e.g. droneaware-node
    • Enable SSH and set a username/password
    • Optional but recommended: enter your WiFi credentials here to avoid needing an Ethernet cable
  4. Select your SD card and click Write.

Step 2 — Boot the Pi

  1. Insert the SD card, plug in your USB Bluetooth adapter, connect power.
  2. Wait 60–90 seconds for the Pi to boot.
  3. SSH into the Pi:
    ssh <your-username>@<pi-ip-address>
    Then switch to root:
    sudo -i

Finding your Pi's IP address: check your router's device list, or if you set a hostname try ssh droneaware-node.local.

Step 3 — Run the Installer

Run this single command:

curl -fsSL https://github.com/fduflyer/DroneAware-Node-Releases/releases/latest/download/install.sh | sudo bash

The installer will:

  1. Display the DroneAware Feeder Node Contributor Agreement — you must type yes to accept before installation proceeds. By accepting, you agree to the terms governing data ownership and network participation. See LICENSE for full terms.

  2. Prompt for a node nickname — a short name to identify this sensor on the DroneAware network (e.g. my-garage, rooftop-east).

  3. Auto-detect your USB WiFi adapter — the installer finds the external adapter automatically. If none is found, it will exit with instructions.

  4. Install system packages and download binaries from the latest release.

  5. Enroll the node — you will be prompted to open droneaware.io/nodes, log in, click Add Node, and paste the enrollment token shown. The node is immediately active on your account — no separate claim step required.

Step 4 — Confirm Your Node is Live

At the end of installation the installer displays:

╔══════════════════════════════════════════════════════════════════════╗
║                    Installation Complete!                           ║
║  Node ID : my-garage                                                ║
╠══════════════════════════════════════════════════════════════════════╣
║  Your node is enrolled and active on the DroneAware network.       ║
║  View it at: https://droneaware.io/nodes                    ║
╚══════════════════════════════════════════════════════════════════════╝

Log into droneaware.io/nodes to see your node on the live map and access:

  • Detection history and alerts
  • Remote node management
  • Network contribution statistics

Useful Commands

# Check service status
sudo systemctl status droneaware-ble
sudo systemctl status droneaware-wifi

# Watch live detection logs
sudo journalctl -u droneaware-ble -f
sudo journalctl -u droneaware-wifi -f

# Edit node config (location, server URL, etc.)
sudo nano /opt/droneaware/config.env
sudo systemctl restart droneaware-ble droneaware-wifi

# Start feeders manually (they start automatically on next reboot)
sudo systemctl start droneaware-ble droneaware-wifi

# To upgrade an existing node
sudo droneaware update

Local / Offline Use

Every detection is also broadcast as a JSON line over UDP to 255.255.255.255:9999 on your local network. Any device on the same LAN can consume detections in real time without any data leaving your network.

Listen from any machine on your LAN:

nc -luk 9999

Or in Python:

import socket, json
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('', 9999))
while True:
    print(json.loads(s.recv(4096)))

Each record looks like:

{"t":1745000000.0,"mac":"fa:0b:bc:12:34:56","radio":"wifi_beacon","rssi":-68,"type":"Location/Vector","lat":40.7128,"lon":-74.0060,"alt":120.5,"speed":8.25,"hdg":270.0,"id":null}

The same detections are also saved to /run/droneaware/detections.jsonl on the Pi — a rolling 60-minute window stored entirely in RAM (no SD card writes, cleared on reboot). You can tail it directly:

tail -f /run/droneaware/detections.jsonl

Local Web UI (v1.4.0+) — works offline (v1.4.5+): If you installed the optional Web UI (sudo droneaware install-webui), point any LAN device at http://<pi-ip>:5000/ for a live detection map. The Web UI runs entirely on the Pi — no internet connectivity to droneaware.io required.

From v1.4.5+, the Web UI also bundles a world-overview basemap inside the binary, so the map renders cleanly even when the browser can't reach CartoDB. Online operators get full street-level detail from CartoDB; offline operators get a recognizable country / state context with drone markers correctly positioned. The fallback is automatic — Leaflet detects failed tile loads and switches sources without a refresh.

HTTP API (v1.4.0+): The Web UI service exposes a small read-only JSON / SSE API on the same port (5000) — often easier to consume than UDP for Home Assistant, Node-RED, Homebridge, or any HTTP-aware automation tool. Unlike UDP, you also get a full snapshot of recent state on connect.

Endpoints (all GET, no auth, LAN-accessible):

Endpoint Returns
/api/detections JSON snapshot of all currently tracked drones
/api/status Node telemetry (version, uptime, load, home location, buffer stats)
/events Server-Sent Events stream — real-time push of each new detection

/api/detections response shape

Top-level object:

Field Type Notes
macs array One entry per tracked drone (see below)
total_events int Raw events held across all drones
mac_count int Number of currently tracked drones
buffer_bytes int Ring buffer bytes in use
buffer_max int Configured max bytes
buffer_pct int 0–100
snapshot_at float Unix seconds at snapshot build time

Each macs[] entry:

Field Type Notes
mac string MAC address, e.g. "fa:0b:bc:12:34:56"
latest object Merged ASTM fields (table below)
first_seen float Unix seconds — first event for this drone
last_seen float Unix seconds — most recent event
age_sec float Seconds since last_seen
event_count int Raw events held for this drone
trail array of [lat, lon] Last 60 unique positions, chronological

The latest object — any field may be null until the relevant ASTM message type is received:

Field Type Range / units Source
t float Unix seconds Broadcast time of most recent event
id string hex UAS-ID — from Basic ID message
lat float [-90, 90] degrees, WGS84 Location/Vector message
lon float [-180, 180] degrees, WGS84 Location/Vector message
alt float meters, geodetic (WGS84) Location/Vector message
speed float m/s, ground speed Location/Vector message
hdg float [0, 360) degrees, compass Location/Vector message
rssi int dBm (negative, e.g. -68) Capture-time signal strength
radio string "wifi_beacon", "wifi_nan", "ble" Capture transport
type string ASTM message type e.g. "Basic ID", "Location/Vector", "System"
operator_lat float [-90, 90] degrees, WGS84 System message
operator_lon float [-180, 180] degrees, WGS84 System message

/api/status response shape

Field Type Notes
version string Node firmware version, e.g. "1.4.0"
uptime_s int Seconds since web_ui started
cpu_temp_c float | null Pi CPU temperature; null on non-Pi hardware
load_1m / load_5m / load_15m float | null Unix load averages
sse_clients int Active SSE subscribers
home object | null {"lat": float, "lon": float, "source": string}
node_id string NODE_ID from config.env
mac_count int Currently tracked drones
event_count int Total events in buffer
buffer_bytes / buffer_max / buffer_pct int Ring buffer stats

/events SSE stream

Each message is a single decoded detection — the same wire format as a UDP broadcast record (see UDP section above). Same field types as the latest object table; aggregate fields (mac_count, event_count, etc.) do not appear on individual events. SSE framing is:

data: {"t":1745000000.0,"mac":"fa:0b:bc:12:34:56","radio":"wifi_beacon","rssi":-68,"type":"Location/Vector","lat":40.7128,"lon":-74.0060,"alt":120.5,"speed":8.25,"hdg":270.0,"id":null}\n
\n

Keep-alive comment (: keep-alive) is emitted every 15 seconds of silence to prevent proxies/browsers from timing out the connection.


Examples

Snapshot:

curl http://<pi-ip>:5000/api/detections | jq .

Live stream in Python:

import requests, json
r = requests.get("http://<pi-ip>:5000/events", stream=True)
for line in r.iter_lines():
    if line.startswith(b"data: "):
        print(json.loads(line[6:]))

Or simply tail it from the shell:

curl -N http://<pi-ip>:5000/events

The API is read-only — there are no POST/PUT endpoints, so it cannot be used to inject detections or change node configuration. Bound to 0.0.0.0:5000 with no authentication; treat it like any other LAN service.

Privacy note: Your node's precise GPS coordinates are never publicly visible. The DroneAware map displays only a 2-mile detection ring around your node — your exact location is kept private.


Testing Your Node

Not seeing any detections and want to confirm your node is working? Run the built-in test command:

sudo droneaware test

This transmits a 60-second sanctioned test flight from your WiFi adapter. Your node captures it, decodes it, and forwards it to the server — the same path a real drone detection takes. A test marker will appear on the Live map within 30 seconds — visible only to you when signed in to the account that owns the node.

Rate limits: 3-minute cooldown between tests, 5 per hour.

Check availability without transmitting:

sudo droneaware test --dry-run

Test detections are tagged server-side and never appear on the public live map or anyone else's dashboard.


Troubleshooting

"USB WiFi adapter required" — installer exits immediately The installer requires a USB WiFi adapter to be present. Connect your Alfa AWUS036N (or compatible monitor-mode adapter) before running the installer, then run it again.

The BLE feeder starts but shows 0 detections This is normal — there may simply be no drones broadcasting Remote ID nearby. Remote ID is only required for drones registered after September 2023, and most recreational fliers are not yet compliant. Detection depends entirely on local drone activity.

WiFi feeder fails to start or keeps restarting

sudo journalctl -u droneaware-wifi -n 50

Common causes:

  • USB WiFi adapter not plugged in or not detected (ip link show)
  • Adapter does not support monitor mode (must be Ralink RT3070 or compatible)
  • Another process (NetworkManager) has taken control of the interface — the installer configures NM to ignore the adapter, but a reinstall of NM may revert this

BLE feeder fails to start or reports a BLE error on startup Your Bluetooth adapter may not support BLE. The Sena UD100 product line spans multiple generations — older variants (including the G01, G02, and G03) are Bluetooth Classic (BT 2.0/2.1) only and will not work for Remote ID, which requires BLE advertising. Newer UD100 variants with Bluetooth 4.0+ are BLE-capable and will work.

Confirm what you have by running:

hciconfig -a | grep "LMP Version"

LMP Version: 2.0 or 2.1 = Bluetooth Classic only, won't work. LMP Version: 4.0 or higher = BLE capable, should work.

If your adapter isn't BLE-capable, you can use the Pi's built-in Bluetooth instead — it supports BLE out of the box on all Pi 4 models, just with shorter range than an external dongle.

The BLE feeder keeps restarting

sudo journalctl -u droneaware-ble -n 50

Common causes:

  • USB Bluetooth adapter not detected — run hciconfig -a to confirm the Pi sees it; unplug and replug the dongle if not
  • Adapter MAC in config.env doesn't match the installed adapter — update BLE_ADAPTER_MAC in /opt/droneaware/config.env and restart

"No internet connection" during install

  • Ethernet: check the cable and that your router assigned an IP (ip addr show eth0)
  • WiFi: verify your credentials are correct, then reboot and try again

I need to change my node's location Log into droneaware.io/nodes, select your node, and update its location there. Node location is managed server-side.


Node File Locations

Path Purpose
/usr/local/bin/ble_feeder BLE Remote ID feeder binary
/usr/local/bin/wifi_feeder WiFi Remote ID feeder binary
/usr/local/bin/droneaware-bt-select Boot-time Bluetooth adapter selector
/opt/droneaware/config.env Node configuration (ID, location, adapters)
/etc/droneaware/token Node credential (written at enrollment)
/etc/systemd/system/droneaware-ble.service BLE feeder systemd unit
/etc/systemd/system/droneaware-wifi.service WiFi feeder systemd unit
/etc/systemd/system/droneaware-bt-select.service BT selector systemd unit

Contributing & Direction

DroneAware Network is an open project and forks are welcome. If you're building on this or experimenting, we'd love to hear what you're working on — especially around detection accuracy, range improvements, or new visualization approaches.

The real power of this project is the shared detection network. If you're running nodes, consider feeding data into the main DroneAware Network so detections benefit everyone.

Join the community on Discord: discord.gg/J4ZHpdgzeb

Already a FlightAware or ADS-B feeder? See the upgrade guide →

Have an idea or improvement? Open an issue or start a discussion — we're actively building.


Verifying Binary Attestation

Every DroneAware Node binary is built in GitHub Actions and cryptographically signed via Sigstore. You can independently verify that any release binary was built from the published source code in a known, controlled environment — not on someone's laptop.

This matters because the Contributor Agreement commits the feeder software to a specific scope of data collection (Section 3.1). Attestation lets you confirm that the binary running on your node actually implements those guarantees.

To verify a binary you downloaded from a release:

gh attestation verify ble_feeder --owner fduflyer gh attestation verify wifi_feeder --owner fduflyer A successful verification confirms the binary was built by GitHub Actions from a specific source commit in this repository.

Requires the GitHub CLI and a free GitHub account:

macOS: brew install gh && gh auth login Debian / Ubuntu / Pi OS: sudo apt install gh && gh auth login


Support


Copyright (c) 2026 DroneAware, LLC. Use of this software is subject to the terms of the DroneAware Feeder Node Software License. See LICENSE for details.

About

DroneAware Node Releases repository

Resources

Security policy

Stars

341 stars

Watchers

9 watching

Forks

Releases

Packages

Used by

Contributors

Languages