Skip to main content
gr-adsb includes a Python webserver (web/webserver.py) that:
  1. Subscribes to decoded plane PDUs over ZeroMQ (default address tcp://127.0.0.1:5001)
  2. Pushes aircraft updates to a connected browser over Socket.IO
  3. Renders live aircraft positions on Google Maps at http://localhost:5000
The webserver is built with Flask, Flask-SocketIO, and gevent, and requires a matching ZeroMQ Pub Sink in the running GRC flowgraph.

Prerequisites

Install the required Python packages before running the webserver for the first time:
pip3 install --user zmq flask flask-socketio gevent gevent-websocket

Starting the webserver and flowgraph

1

Open a terminal and navigate to the web directory

cd gr-adsb/web/
2

Start the webserver

Run the webserver using either of the following commands:
python3 webserver.py
The server starts listening on 127.0.0.1:5000 for HTTP connections and subscribes to ZeroMQ messages on 127.0.0.1:5001.
3

Open the GRC flowgraph and enable ZeroMQ

In GNU Radio Companion, open gr-adsb/examples/adsb_rx.grc. Ensure the ZeroMQ Pub Sink block is enabled and configured to publish to:
tcp://127.0.0.1:5001
If the ZeroMQ Pub Sink block is disabled or bypassed in the flowgraph, the webserver will not receive any data and the map will remain empty.
4

Run the flowgraph

Click Execute (or press F6) in GRC to start the SDR receiver and begin decoding.
5

Open the map in a browser

Navigate to:
http://localhost:5000
Aircraft positions will appear and update in real time as new decoded messages arrive from the flowgraph.
The webserver and the GRC flowgraph can be started in either order. If the flowgraph is running before the webserver starts, the webserver will begin receiving buffered and new ZeroMQ messages as soon as it connects. If the webserver starts first, it will wait for the flowgraph’s ZMQ publisher to come online.

Address configuration

The webserver source defines its addresses as module-level constants:
HTTP_ADDRESS = "127.0.0.1"
HTTP_PORT = 5000

ZMQ_ADDRESS = "127.0.0.1"
ZMQ_PORT = 5001
If you need to change the HTTP port or ZMQ address (for example, to run the webserver on a remote machine), edit these values directly in web/webserver.py.

How it works

The webserver runs a background thread (zmq_thread) that loops indefinitely, receiving serialised PMT PDUs from the ZeroMQ socket. Each PDU contains a dictionary of decoded aircraft fields (ICAO address, callsign, altitude, speed, heading, latitude, longitude, etc.). The thread deserialises each PDU and emits an updatePlane Socket.IO event to all connected browser clients:
pdu = pmt.deserialize_str(pdu_bin)
plane = pmt.to_python(pmt.car(pdu))
socketio.emit("updatePlane", plane)
The browser-side JavaScript handles updatePlane events to create or update aircraft markers on the Google Maps view.

Build docs developers (and LLMs) love