The complete documentation, published openly — so you can see exactly what you are buying, and what data licences come with it, before you pay.
Offline ADS-B aircraft radar. Native GTK and Cairo — no browser, no map tiles, no internet. Every aircraft is identified from a database on your own disk.
Thank you for buying it.
| Read this | For |
|---|---|
INSTALL.md |
getting it running, step by step |
USAGE.md |
keys, views, pointing it at a receiver |
DEPENDENCIES.md |
everything it needs, per distribution |
DATA.md |
where the data comes from, and the licences you inherit |
ATTRIBUTION.md |
credits you must keep — please leave this file in place |
LICENSE |
what you may and may not do with this software |
# 1. dependencies (Debian/Ubuntu/Raspberry Pi OS/Kali)
sudo apt install python3 python3-gi python3-gi-cairo python3-cairo \
gir1.2-gtk-3.0 gir1.2-pango-1.0
# 2. install
install -Dm755 uc-adsb ~/.local/bin/uc-adsb
# 3. build the offline airframe database
python3 tools/build-aircraft-db.py
# 4. run — local decoder, or one on your network
uc-adsb
UC_ADSB_FEED=http://feeder.local/tar1090/data/aircraft.json uc-adsb
If step 3 cannot find the source data it tells you exactly how to fetch it.
uc-adsb the program (readable Python, modify it freely)
tools/build-aircraft-db.py builds the offline airframe database
packaging/uc-adsb.desktop desktop launcher
INSTALL.md USAGE.md DEPENDENCIES.md DATA.md ATTRIBUTION.md LICENSE
It identifies aircraft offline. ~563,000 airframes on disk. Web trackers ask a server for a tail number; this asks a file. Works with the network unplugged.
Your decoder does not have to be here. Point it at any readsb or tar1090 box on your network. The antenna goes where the sky is; the screen goes where you are.
No browser. GTK and Cairo drawing directly. Starts in about a second and is comfortable on a Raspberry Pi.
The map is optional. Without one you get a clean scope — rings, aircraft and trails. Some operators prefer that.
Full detail in DEPENDENCIES.md.
Bug reports, questions and feature requests: support@fieldoffgrid.com
Please include the output of the Setup view — it shows your feed, its error if any, and whether the databases loaded, which answers most questions immediately.
Not for navigation, separation or collision avoidance. ADS-B data is
unvalidated and can be absent, delayed or wrong. See LICENSE.
There is nothing to compile. uc-adsb is a single Python program — installing it means putting it somewhere on your PATH and making sure its dependencies and data are in place.
Work through these in order. Each step tells you how to check it worked before you move on, so a failure is obvious immediately rather than three steps later.
Follow DEPENDENCIES.md for your distribution, then verify:
python3 -c "import gi; gi.require_version('Gtk','3.0'); from gi.repository import Gtk; print('GTK ok')"
python3 -c "import cairo; print('cairo ok')"
Both must print. If either fails, uc-adsb cannot start, and no later step will fix it.
For yourself:
mkdir -p ~/.local/bin
install -m755 uc-adsb ~/.local/bin/uc-adsb
Make sure ~/.local/bin is on your PATH:
echo $PATH | tr ':' '\n' | grep -q "$HOME/.local/bin" || \
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.profile
Or system-wide:
sudo install -m755 uc-adsb /usr/local/bin/uc-adsb
Check:
which uc-adsb
This is what gives you registrations and types offline. Full detail and licence
information in DATA.md.
If you already run tar1090:
python3 tools/build-aircraft-db.py
If you do not:
git clone --depth 1 https://github.com/wiedehopf/tar1090-db /tmp/tar1090-db
python3 tools/build-aircraft-db.py --src /tmp/tar1090-db/db
Check:
python3 -c "
import sqlite3, os
p = os.path.expanduser('~/.local/share/uc-adsb/aircraft.sqlite')
print(sqlite3.connect(p).execute('select count(*) from ac').fetchone()[0], 'airframes')"
Expect several hundred thousand. uc-adsb runs without this — you just get bare hex codes instead of tail numbers.
uc-adsb needs a decoder producing aircraft.json. Either:
a) a decoder on this machine — nothing to configure, the default
/run/readsb/aircraft.json is used. Confirm it exists:
ls -l /run/readsb/aircraft.json
b) a decoder elsewhere on your network — find the URL and test it:
curl -s http://feeder.local/tar1090/data/aircraft.json | head -c 200
Set it permanently in Setup → Feed once the program is running, or per-run:
UC_ADSB_FEED=http://feeder.local/tar1090/data/aircraft.json uc-adsb
uc-adsb
For a desktop entry:
install -Dm644 packaging/uc-adsb.desktop ~/.local/share/applications/uc-adsb.desktop
Not required — without one you get a clean scope. If you want streets behind the
traffic, see DATA.md §2, then:
UC_ADSB_MAP=/path/to/map.sqlite uc-adsb
| Symptom | Cause | Fix |
|---|---|---|
ModuleNotFoundError: No module named 'gi' |
PyGObject missing | step 1 — install the distro package, not pip |
Gtk couldn't be initialized |
no display | needs a graphical session; it is a GUI |
| Window opens, no aircraft, Setup shows a feed error | decoder unreachable | the error names the reason — read it |
| Aircraft appear as bare hex codes | no aircraft database | step 3 |
warning: base map missing |
no map | expected, and harmless — see step 6 |
Setup shows the exact feed error rather than an empty screen, because a remote feed fails for boring, fixable reasons and "no aircraft" tells you none of them.
rm -f ~/.local/bin/uc-adsb ~/.local/share/applications/uc-adsb.desktop
rm -rf ~/.config/uc-adsb ~/.local/share/uc-adsb
uc-adsb
Switch with the bottom bar, or keys 1–4.
| Radar | aircraft on the map, with trails, range rings and labels |
| List | sortable table — flight, type, altitude, speed, track, distance, signal |
| Flight | everything known about one aircraft |
| Setup | feed, receiver position, display options |
1–4 |
switch view |
Tab / Shift-Tab |
cycle target |
Enter |
open the selected target |
+ / - |
zoom |
| arrows | pan |
g |
centre on your receiver |
l |
labels on/off |
k |
range rings on/off |
t |
trails on/off |
F5 |
refresh |
F11 |
fullscreen |
Esc |
deselect |
q |
quit |
Mouse and trackball: click selects the nearest aircraft, hold-left and drag pans, wheel zooms.
uc-adsb reads the standard aircraft.json from readsb or dump1090. It can be a
local file or an HTTP URL — your decoder does not have to be on the machine
you are looking at.
# a decoder on this machine (the default)
uc-adsb
# a decoder anywhere on your network
UC_ADSB_FEED=http://feeder.local/tar1090/data/aircraft.json uc-adsb
Common paths:
| Setup | Feed |
|---|---|
| readsb, same machine | /run/readsb/aircraft.json |
| dump1090-fa, same machine | /run/dump1090-fa/aircraft.json |
| tar1090 on the network | http://HOST/tar1090/data/aircraft.json |
| readsb's own web output | http://HOST/data/aircraft.json |
Set it permanently in Setup → Feed. It is saved, so you only do it once.
$UC_ADSB_FEEDoverrides the saved setting for that run only. That is deliberate: a one-off look at someone else's receiver should not quietly rewrite your own configuration.
Switching feeds clears the tracked aircraft — they belonged to the old receiver, and mixing two coverage areas on one screen would be worse than useless.
Range rings, distances and bearings need to know where you are.
g to
centre on it, or Setup → Set home = GPS.Aircraft colour is altitude — the scale runs from low to high, so a climbing aircraft visibly changes colour as it goes.
The status bar, left to right: aircraft count (and how many have a position), maximum range, message rate, receiver state, time. A steady message rate with few positions usually means a poor antenna rather than a software problem.
Squawk 7500, 7600 and 7700 are highlighted as HIJACK, RADIO FAIL and EMERGENCY. 7700 in particular is rare and usually a diversion.
| Default | ||
|---|---|---|
UC_ADSB_FEED |
/run/readsb/aircraft.json |
file path or http(s):// URL |
UC_ADSB_DB |
~/.local/share/uc-adsb/aircraft.sqlite |
airframe database |
UC_ADSB_MAP |
~/.local/share/uc-nav/map.sqlite |
base map, optional |
UC_ADSB_VIEW |
radar |
view to open on |
Configuration is saved to ~/.config/uc-adsb/config.json.
Perfectly supported. You get rings, aircraft, trails and labels on a clean scope — which some operators prefer to a busy street map. The program warns once on start and carries on.
No aircraft at all. Open Setup and read the feed line — it names the actual error. If the feed is fine and the count is genuinely zero, the problem is at the antenna, not here.
Aircraft show as bare hex codes. The airframe database is missing or empty.
See INSTALL.md step 3.
Aircraft with no position. Normal. An aircraft must transmit a position message, and until it does you have its identity but not its location — that is what "5 (3 pos)" in the status bar is telling you.
Start/Stop receiver buttons missing. Expected on a remote feed. They control
a local systemd readsb, which means nothing when you are watching a decoder on
another machine, so they are hidden rather than left to appear to work.
Everything uc-adsb needs, what it is for, and how to install it. Versions are what it was verified against — older will usually work, and the program tells you plainly if something is missing rather than failing obscurely.
| Verified | Why | |
|---|---|---|
| Python | 3.13.5 (3.9+ expected fine) | the program is Python |
PyGObject (gi) |
3.x | GTK bindings |
| GTK | 3.24 | the interface |
| PangoCairo | 1.0 | text on the map |
| pycairo | 1.27.0 | all drawing |
| SQLite | 3.46.1 | the aircraft and map databases |
Only two non-standard-library imports exist in the whole program — gi and
cairo. Everything else (json, socket, sqlite3, urllib, math,
struct, colorsys, subprocess) is Python's standard library, so there is no
pip dependency tree to resolve and nothing to pin.
Debian, Ubuntu, Raspberry Pi OS, Kali
sudo apt install python3 python3-gi python3-gi-cairo python3-cairo \
gir1.2-gtk-3.0 gir1.2-pango-1.0
Fedora
sudo dnf install python3 python3-gobject python3-cairo gtk3
Arch
sudo pacman -S python python-gobject python-cairo gtk3
openSUSE
sudo zypper install python3-gobject python3-gobject-Gdk python3-cairo gtk3
PyGObject is deliberately not installed with pip. The pip build needs GTK development headers and a compiler and frequently fails; every distribution ships a working binary package. Use it.
python3 -c "import gi; gi.require_version('Gtk','3.0'); from gi.repository import Gtk; print('GTK', Gtk.MAJOR_VERSION, Gtk.MINOR_VERSION)"
python3 -c "import cairo; print('pycairo', cairo.version)"
Both printing a version means you are ready.
uc-adsb does not talk to the radio itself — it reads the JSON a decoder produces. You need one of these, either on this machine or another on your network:
wiedehopf's
install-readsb.sh is the usual route)Both write aircraft.json. See USAGE.md for pointing uc-adsb at either.
Any RTL2832U dongle. A 1090 MHz antenna matters far more than the dongle does — a filtered preamp and a properly cut antenna are the difference between ten aircraft and two hundred.
Nothing to install for uc-adsb itself; the decoder owns the radio.
| Why | Without it | |
|---|---|---|
| gpsd | sets your receiver position automatically | set it by hand in Setup |
| base map | street map behind the traffic | clean scope: rings, aircraft, trails |
| systemd | Start/Stop receiver buttons | buttons are hidden; use your own init |
Not software, but the program needs them. Full detail — including licences — in
DATA.md.
| File | Default location | Required |
|---|---|---|
aircraft.sqlite |
~/.local/share/uc-adsb/ |
for registration/type lookup |
map.sqlite |
~/.local/share/uc-nav/ |
optional |
Both paths are overridable — see USAGE.md.
uc-adsb needs one dataset to do its job and can optionally use a second. Neither is invented by us, and both come with obligations you inherit the moment you use them. This document exists so you can meet those obligations without having to go and research them yourself.
Short version: the aircraft database is free to use commercially provided you credit it. The base map is free to use provided you credit it, and if you pass the map database on to someone else it must stay under the same open licence.
What it does. Turns the 24-bit ICAO hex code in every ADS-B message into a registration, an aircraft type and a description — offline. Around 563,000 airframes.
Where it comes from. The database is maintained by Mictronics and redistributed for tar1090 by wiedehopf:
Its own upstream sources are ICAO Doc 8643 (aircraft type designators) and FAA JO 7340.2 (operator three-letter designators and callsigns).
Licence: Open Data Commons Attribution License v1.0 (ODC-By 1.0). https://opendatacommons.org/licenses/by/1-0/
What ODC-By allows. Use, modification and redistribution, including commercially and including inside a paid product. It is an attribution licence, not a non-commercial one and not a share-alike one.
What it requires of you. Credit the source. Keep the notice with the data.
The credit is already written for you in ATTRIBUTION.md in this archive —
leave that file in place and you have met the requirement.
Option A — build it yourself (recommended).
If you run tar1090 you already have the source data on disk. The builder in
tools/build-aircraft-db.py turns it into the SQLite file uc-adsb wants:
python3 tools/build-aircraft-db.py
This is the recommended route for two reasons: your data stays as current as your tar1090 install, and nothing has to be redistributed.
Option B — fetch the source data directly.
Without tar1090, clone the database repo and point the builder at it:
git clone --depth 1 https://github.com/wiedehopf/tar1090-db
python3 tools/build-aircraft-db.py --src tar1090-db/db
Option C — use the prebuilt copy, if one shipped with your download.
Check whether data/aircraft.sqlite is present in this archive. If it is, it
was built from the sources above and ATTRIBUTION.md carries the required
credit. If it is not present, use A or B — that is not an omission, it is
deliberate, so that you always know exactly where your data came from.
uc-adsb runs perfectly well without a map — you get range rings, aircraft, trails and labels on a clean scope, which some operators prefer. Everything below applies only if you want a street map behind the traffic.
Where it comes from. The map is built from OpenStreetMap data.
Licence: Open Database License v1.0 (ODbL 1.0). https://opendatacommons.org/licenses/odbl/1-0/
What ODbL allows. Use, modification and redistribution, including commercially.
What it requires — and this one has a share-alike clause, so read it.
map.sqlite is a Derivative
Database, because it contains the actual road, water and place geometry.
If you distribute that file to anyone, you must offer it under ODbL —
you cannot place it under a more restrictive licence.In practice: showing the map is unencumbered beyond the credit. Handing the
.sqlite to somebody else obliges you to hand it over as ODbL.
Build your own region from an OpenStreetMap extract. Geofabrik publishes
per-country and per-state .osm.pbf files:
https://download.geofabrik.de/
A map is inherently regional — a Florida map is no use in Bavaria — which is why one is not bundled. Build the area you actually fly over.
Not a dataset — it is your own receiver, or one you have been given access to.
uc-adsb reads the standard aircraft.json produced by readsb or
dump1090, either as a local file or over HTTP. See USAGE.md.
If you point uc-adsb at somebody else's receiver, that is between you and them. Public aggregator APIs generally have terms restricting redistribution and commercial use; uc-adsb does not use any, and we would suggest not pointing it at one without reading them.
| Data | Licence | Commercial use | You must |
|---|---|---|---|
| Aircraft database (Mictronics) | ODC-By 1.0 | Yes | Credit the source — see ATTRIBUTION.md |
| Base map (OpenStreetMap) | ODbL 1.0 | Yes | Credit "© OpenStreetMap contributors"; keep the DB under ODbL if you pass it on |
| FAA Releasable Aircraft DB | Public domain (US) | Yes | Nothing |
| Your own ADS-B receiver | Yours | Yes | Nothing |
Licence terms were checked against the sources listed above. Licences change; if you are building something commercial on top of this, check the links yourself rather than relying on a snapshot in a text file. Nothing here is legal advice.
uc-adsb uses open data that requires credit. Keep this file with the program. If you redistribute uc-adsb, or publish screenshots or a service built on it, these credits travel with it.
Contains information from the Mictronics aircraft database, redistributed via wiedehopf/tar1090-db, which is made available under the Open Data Commons Attribution License v1.0.
Upstream sources: ICAO Doc 8643 (aircraft type designators) and FAA JO 7340.2 (operator designators and callsigns).
ODC-By permits commercial use and redistribution. Attribution is the condition.
Map data © OpenStreetMap contributors, available under the Open Database License.
ODbL has a share-alike clause on databases. Displaying a map needs only the
credit above. If you pass a derived map database to anyone else, it must go
under ODbL. See DATA.md §2.
uc-adsb is built on GTK, Cairo, Pango and PyGObject, each under the GNU LGPL, and on Python's standard library under the PSF licence. It reads the output of readsb or dump1090 but does not include or link against either.
Copyright © 2026 Chris Rose. See LICENSE.