A comprehensive flight-tracking and logging program that renders ADS-B aircraft info to an RGB-Matrix display.
This is a personal/hobbyist project that was heavily inspired by Colin Waddell's project, but supplements flight information of
nearby aircraft with real-time ADS-B (Automatic Dependendent Surveillance - Broadcast) and UAT (Universial Access Transceiver) data from dump1090 and dump978.
Uses the tar1090 database for aircraft type and owner along with an internal database for airline lookup by callsign.
Uses the FlightAware API to get an aircraft's departure and destination airports.
Designed primarily to run on a Raspberry Pi and Raspberry Pi OS, but can be run on other setups (your mileage may vary).
Note
Fun fact: this is also the author's second-only Python project.
Table of Contents
Show/Hide images (animated gifs)
Neat 👍 |
I like this, how do I build my own?
Coming Soon™.
If you want one, I can also build one for you. (also Coming Soon™)
The Changelog has all the details, but as a bulleted list:
- Visualize and figure out what aircraft are flying nearby your location, in a cool-looking way!
- Shows an aircraft's callsign (or registration as fallback), distance and direction from your location, the aircraft's country of registration, current altitude, and speed, all provided from
dump1090 - With API access you also can see the origin and destination airport, as well as how long the aircraft has been flying
- If you don't want to use the API, there's an available "Enhanced Readout" mode that shows even more aircraft info from
dump1090, such as latitude, longitude, ground track, vertical speed, and RSSI - With v.6.0.0 and newer, you can see additional info like aircraft type, airline, and owner, all without needing API access
- There are a total of 3 different layouts for aircraft info!
- Shows an aircraft's callsign (or registration as fallback), distance and direction from your location, the aircraft's country of registration, current altitude, and speed, all provided from
- It's a neat looking clock when there aren't any aircraft flying overhead
- When
dump1090is running, shows overall stats like how many aircraft you're tracking at the moment, how many aircraft flew by today, and the furthest aircraft you can detect - Display sunrise and sunset times, detailed signal stats for your ADS-B receiver, extended calendar info, and even local weather info
- When
- Extensive logging and console output capabilities as a core function
- Easily configured, controlled, monitored, and updated within a web browser
- Can emulate an RGB Matrix display in a web browser if you don't have the actual hardware
- Works offline once initial setup is complete (albeit, with no API functionality and as long as
dump1090is running on the same system) - Designed to run 24/7
More Features
- Automatically switches to other aircraft if more than one is within the area
- Does not need to run on the same hardware that
dump1090is running from - Reads
dump978data if it's present as well - Clock uses your system's locale for weekday/month abbreviations
- Customizable features such as:
- Range and height ceiling that aircraft need to be in for detailed tracking
- Units (aeronautical, metric, or imperial)
- Clock style (12 hour or 24 hour)
- Brightness based on time of day or when there's an active aircraft shown
- API limiting per day, by monthly cost, or even by the hour (those API calls can get expensive)
- Track a specific aircraft once it's detected by your ADS-B receiver
- Every element on the display can have its color set
- Switch between font styles
- and more
- Built to work with PiAware/FlightFeeder, ADSBExchange, Ultrafeeder, and ADSB.im setups
- Highly optimized and fast
- Worst case takes ~25ms on average from raw data to fully parsed, filtered, run through the selection algorithm, and formatted
- The above statistic taken from a Rasberry Pi Zero 2W w/ 32-bit OS operating as a 99.9th percentile (worldwide) ADS-B+UAT receiver at peak traffic while sending data to multiple ADS-B aggregators with MLAT
- Worst case takes ~25ms on average from raw data to fully parsed, filtered, run through the selection algorithm, and formatted
- Small memory footprint once settled (10-40 MiB)
- Fully Python based
- The python script has been verified to run in both Linux (Debian) and Windows. (MacOS untested)
- All installed components confirmed to run on
ARMv7,ARMv8,x86_64,i686 - Runs from a initialization script that handles everything such as initial setup and running the python script (Linux only)
- Set up to automatically start on boot via
systemd
- Set up to automatically start on boot via
- Easily update to latest builds here on Github
- Automagically migrate settings, even if new options appear or are removed in the future
- Program state is available in a json file for use elsewhere
- Logs events when you detect aircraft beyond typical ADS-B range limits (DXing)
- Automatically tracks aircraft which report distress signals
- Robust and hard-to-break
- Unique tools and custom-developed fonts that can be used in other projects (don't forget to credit me)
- Constant development
- Adequate documentation
Show/Hide
Show/Hide All
Using this project assumes you have the following:
- A working
dump1090instance or similar interface whereaircraft.jsoncan be read/accessed- Ex:
tar1090/readsb,piaware/skyaware,dump1090-fa,dump1090-mutability- Note: the script will automatically look at these locations and choose which one works
- This script does not need to be on the same device that
dump1090is running from (see Configuration section) - Your ADS-B decoder must output in aeronautical units (nautical miles, knots, feet)
- Ex:
- The latest Python (>=3.10)
- At least 100 MB of available disk space
- A working internet connection for setup
gitneeds to be installed- for Linux distros:
- Basic knowledge of how to use
bashor similar terminal sshaccess if running headlessaptas the package manager- Root access (necessary for accessing the RGBMatrix hardware)
systemdbased system
- Basic knowledge of how to use
- The rgbmatrix library installed and present on the system
- You can use the initialization script to install this, see this section after reading through the setup
- If you did not use the built-in install method above, the below points need to be followed:
- Refer to adafruit's guide on how to get this working if it's not installed already
- It needs to be accessible as a Python module globally or in the same home directory of the user that installed FlightGazer
- Must be built using the adafruit script
- Note: if using a Raspberry Pi, the core
rgbmatrixlibrary doesn't run on a Pi 5 or newer. Use a Pi 4 or older.
rgbmatrixdoes not need to be installed to run FlightGazer, however. (see Usage section)
- The physical RGB matrix hardware (again, not strictly necessary)
- Recommended: Using the adafruit matrix bonnet
- Using
64x32sized, HUB75 type matrix display (this is the only layout this script was designed for) - Other matrix displays and setups can be used as well using advanced settings
- Your location set in
dump1090 - A console that can interpret ANSI escape sequences (should be most modern ones)
- If using a Raspberry Pi, use a model that has multiple CPU cores (Raspberry Pi 3/Raspberry Pi 2W or newer)
- Not using a combined feed for the data source (you would know if you set this up)
- A FlightAware API key (optional) for getting additional aircraft information such as origin/destination airports
- It is highly recommended to generate a key that will only be used for FlightGazer for accurate cost tracking
- A running
dump978instance if you're in the US and live near airports that handle general aviation more than commercial flights
tl;dr You need a running dump1090 instance and if it's not running on the same device as FlightGazer you need to know a valid URL to access its data.
You don't actually need a physical RGB display, but it's recommended. You can install this hardware later if you choose to do so.
Other ADS-B decoders will not work. Your site location needs to be set for most of the functionality to work.
Note: FlightGazer will not work with UAT-only setups and assumes single-site decoders (not a combined feed).
Not tracking planes yet and want to use this project?
- Follow this guide entirely and use a Raspberry Pi
- Get SSH access (go to System → Management from the main webpage)
- Press the Show Password button in the Generate New Root Password section
- Copy the password and press the Accept button
- With your SSH client, log into the device at
root@adsb-feeder.local
- Continue the below steps and install the web interface as well
- You can add the RGB Matrix hardware later, expand the prerequisites above for the hardware+software set-up
Make sure you meet the above prerequisites.
There are two approaches:
- Using the web-app (recommended)
- Installing the traditional way (a little more involved)
To begin:
git clone --depth=1 https://github.com/WeegeeNumbuh1/FlightGazer
cd FlightGazer
Now, choose either one of these methods:
Run this command exactly:
sudo bash FlightGazer-init.sh -c && echo y | sudo bash install-FlightGazer-webapp.shWatch the output closely. If the install is successful, near the end of the output will be the URL that you need to navigate to in order to complete the setup.
Once at that webpage, configure settings first and start/restart FlightGazer to apply those settings. Done!
If you want finer control over the installation process and didn't use the web-app method above, follow these steps:
- Edit the configuration first (see the section below)
- Run
sudo bash FlightGazer-init.sh- Optional: if you just want to try out FlightGazer without a permanent install, pass the
-lflag at the end of the above command - Additional operating modes are explained here
- Optional: if you just want to try out FlightGazer without a permanent install, pass the
- To make management easier later on, install the web-app
- Run
sudo bash install-FlightGazer-webapp.sh
- Run
Edit config.yaml which is found in the same directory as the main script itself.
If you changed any setting, FlightGazer must be restarted for the change to take effect.
Example:
cd /path/to/Flightgazer
nano config.yaml
# press Ctrl+O to save, Ctrl+X to exitEdit colors.py in the setup folder of FlightGazer.
For useful settings with specific setups (e.g. remote dump1090 feeders, custom webinterfaces, etc.), see the tips-n-tricks document.
The main python script (FlightGazer.py) is designed to be started by the FlightGazer-init.sh file.
When FlightGazer is installed, you can use the command sudo systemctl start flightgazer to start it if it's not already running.
Important
By default, the script is designed to run at boot (via systemd with flightgazer.service).
It's much more convenient to check how FlightGazer is running through the web-app.
However, you can also check its status with any of the following commands:
sudo tmux attach -d -t FlightGazer # press 'Ctrl+B' then 'd' to close
# or
systemctl status flightgazer # press 'q' to exit
# or
less /path/to/FlightGazer/FlightGazer-log.log # read the log output, press 'q' to quit
# or
less /run/FlightGazer/current_state.json
# or
journalctl -u flightgazer # use arrow keys to navigate, press 'q' to exitThe script and python file are designed to run interactively in a console. If you run the following command manually:
sudo bash /path/to/FlightGazer/FlightGazer-init.sh
The script automatically detects that you're running interactively and will display realtime output, like so:
Example output
Note: In the above gif, FlightGazer is operating in verbose mode. When normally running, there's way less information overload.
FlightGazer-init.sh supports optional arguments that adjust the behaviors of the FlightGazer installation and main python script. Expand the table below to see all possible operating modes. Multiple flags can be passed as well.
Table of operating modes
| Flag | Enables interactive mode in FlightGazer? |
What it does |
|---|---|---|
| (no flag) | ❌ | Default operating mode when not run as a service. Only prints log entries to stdout.Will use rgbmatrix. Uses RGBMatrixEmulator as a fallback. |
-d |
✅ | Do not load any display driver. Only print console output. Overrides -e. |
-e |
❌ | Use RGBMatrixEmulator as the display driver instead of actual hardware.Display by default can be seen in an internet browser. (see the next section) |
-f |
✅ | No Filter mode. Ignores set RANGE and HEIGHT_LIMIT settings and shows all aircraft detected.Display will never show aircraft details and remain as a clock. Useful for low traffic areas. |
-t |
✅ | Run in tmux. Useful for long-running interactive sessions. Default operating mode when started as a service. |
-c |
❌ | Only install/force-check dependencies and don't start the main script. |
-v |
❌ | Enable verbose/debug messages to be displayed/logged from the main script. |
-l |
❌ | Live/Demo mode. Does not install service and runs FlightGazer from dependencies in /tmp. |
-m |
❌ | Run the rgbmatrix install/update script only.Does not start FlightGazer. Overrides all other options. |
-h |
❌ | Print the help message. |
Advanced use
There's nothing stopping you from calling the python file directly. However FlightGazer-init.sh was designed to make running it smoother by handling the initial setup, making sure all the dependencies are there before running the actual python script, and automatically using the full paths for both the virtual python environment binaries and for the script itself, along with handling any arguments/flags that need to be passed.
You can run it like so:
sudo /etc/FlightGazer-pyvenv/bin/python3 /path/to/FlightGazer/FlightGazer.py
The main python file accepts almost all the same arguments as the initialization script, but you can always pass -h to see all possible operating modes.
When FlightGazer does not detect the physical RGB Matrix hardware/software, it falls back to using the display emulator.
To see the display, you can:
- Navigate to the web-app and follow the link to it, or
- Go directly to
http://<IP-address-of-device-running-FlightGazer>:8888
A viable setup if not using an RGB Matrix display is to:
- Use a second device (laptop, tablet, smart fridge, smart home display, etc.)
- Setting the display to never sleep
- Going to the emulator page in a web browser
- Set the window to full screen
Important
Running the emulator is slow!, especially on single-board computers such as the Raspberry Pi.
Animations might be choppy or laggy depending on your system and enabled settings. (expect about 8-12 FPS on a Raspberry Pi 3/Zero 2W)
When FlightGazer is running, it writes a JSON to /run/FlightGazer/current_state.json and updates every LOOP_INTERVAL (2 seconds by default).
Additionally, if you're using the web-app, this same JSON is also available at the /data/current_state.json endpoint.
You can poll this data for your own use (e.g. a InfluxDB/Telegraf/Grafana stack) and get stats like aircraft details, how long aircraft are in your area, FlightGazer's operating performance, and more.
See the JSON details for a full explanation of this data.
There's also an additional file flybys.csv in the same directory that FlightGazer resides in, which tracks hourly cumulative counts of aircraft flybys and API stats. This file is also used by FlightGazer to maintain its daily counts whenever it's restarted.
It's easier with the web-app.
If that's not in use, to shutdown FlightGazer, do any one of the following:
Show/Hide
# preferred method
sudo systemctl stop flightgazersudo tmux attach -d -t FlightGazer
# then, press 'Ctrl+C' to stop# if you started FlightGazer interactively and manually
Ctrl+CTo restart, simply do the following:
Show/Hide
sudo systemctl restart flightgazer &
# or, if it's currently not running:
sudo systemctl start flightgazer &or, you may start it manually.
See the Output Reference document.
What the initialization script does
- Checks if there is an internet connection
- Checks if Python is installed and also checks its version with the minimum requirements
- Checks if
first_run_completeexists- Checks last modified date: if greater than 3 months, runs updates for installed dependencies
- If file exists and is new-ish, then this isn't an initial installation and we just run the main python script
- Updates package list
- Installs:
- python3-dev
- libjpeg-dev
- python3-numpy
- python3-venv
- tmux
- Create a new systemd service
flightgazer.serviceif not present- Also creates a systemd service for the boot splash screen
flightgazer-bootsplash.serviceas well, only if thergbmatrixlibrary is present
- Also creates a systemd service for the boot splash screen
- Write out
RGBMatrixEmulatorconfig file - Makes virtual python environment at
etc/FlightGazer-pyvenv - Updates
pipas necessary and installs the following python packages in the virtual environment:- rgbmatrix (if it's not installed globally and is present in the user's folder)
- requests
- pydispatcher
- schedule
- psutil (usually provided in Raspberry Pi OS)
- suntime
- ruamel.yaml
- orjson
- RGBMatrixEmulator
if the web app is installed as well: - Flask
- gunicorn
- Downloads the
tar1090-dbaircraft database and generates a sqlite3 database that can be used by FlightGazer - Writes
first_run_completeblank file toetc/FlightGazer-pyvenvto show initial setup is done - Runs main python script with desired flags
Running on Windows
You will need to put in some elbow grease here.
[!IMPORTANT] You're likely not going to be running
rgbmatrixon Windows. Instead, useRGBMatrixEmulator.
pip install psutil
python3 -m venv --system-site-packages "\path\to\new-python-venv"
cd "\path\to\new-python-venv\Scripts"
pip install requests pydispatcher schedule suntime ruamel.yaml orjson RGBMatrixEmulatorIf you don't care for running in a virtual environment, skip the python3 -m venv and cd "path\to..." lines and install the packages globally.
Run FlightGazer as so:
\path\to\new-python-venv\Scripts\python \path\to\FlightGazer\FlightGazer.py -i -e
or, if you didn't set up the virtual environment:
python \path\to\FlightGazer\FlightGazer.py -i -e
Pass -h to see all operating modes.
Useful commands
Terminating FlightGazer-related processes manually (Linux):
# Just the main FlightGazer process
kill -15 $(ps aux | grep '[F]lightGazer\.py' | awk '{print $2}')
# The web interface (using systemctl is recommended over this)
kill -15 $(ps aux | grep 'FG-webapp.py' | awk '{print $2}')Changing systemd startup command
sudo nano /etc/systemd/system/flightgazer.service
systemctl daemon-reloadDisabling startup at boot
sudo systemctl disable flightgazer.serviceWant to use the same aircraft databases this project uses?
Check the utilities directory.
Version v.2.x and newer:
# recommended
sudo bash /path/to/FlightGazer/update.shTo use the most up-to-date version of the update script:
# alternative approach
cd /path/to/FlightGazer
wget -O update.sh https://raw.githubusercontent.com/WeegeeNumbuh1/FlightGazer/refs/heads/main/update.sh
sudo bash update.shNote
FlightGazer will never implement any self-updating mechanism or any form of push updates.
An update must be run explicitly by the end user.
The initialization script, every 3 months after the last update, will check for updates to the aircraft database and other system components required to run, at startup.
When running the update script, it will pull data only from this repository and nowhere else.
Windows
You can run git clone --depth=1 https://github.com/WeegeeNumbuh1/FlightGazer \a\different\directory and manually migrate your config.
Upgrading from v.1.x to v.2.x and newer
Use the alternative approach above.
The migrator cannot migrate v.1.x configuration files to the newer format so you must manually migrate your settings.
sudo bash /path/to/FlightGazer/uninstall.sh
Windows
Simply delete the folder (and the virtual python environment if you set that up as well).
If your question isn't listed in the FAQ's, open an issue here on GitHub.
Warning
FlightGazer must constantly run as root.
- This is unavoidable due to the need to interact with low-level hardware to drive the RGB display.
- The rgbmatrix library is capable of dropping root privleges, however doing so will cause essential write operations to fail.
- Additionally, not running as root will reduce performance, which we need the most of since this is all based on Python.
- The FlightGazer service is designed to be a system service and starts the main script with higher CPU and disk priority.
- Related processes like the web-app must also run as root since it needs to be able to start or stop the FlightGazer service.
- Even though the emulator does not need to run as root, it will still inherit root permissions due to the way FlightGazer runs.
- Same goes for running in
NO_DISPLAYmode (-d).
- Same goes for running in
- The rgbmatrix library is capable of dropping root privleges, however doing so will cause essential write operations to fail.
- If you're not comfortable with this, do not use this project.
- or, suggest code changes which may reduce the attack surface.
See also: Other Quirks & Features™
Found a bug? Want to suggest a new feature? Open an issue here on GitHub.
If you do encounter an issue, provide a copy of FlightGazer-log.log which can be found in the FlightGazer directory.
If using the web-app, also provide the FlightGazer-initialization.log which can be downloaded from "Details and Logs".
* (dust) *
Catch up on lore: Changelog.txt.
Faraway ideas:
-
Docker image?(unlikely) - Settings management from webpage → Available here
- Support display output to a FlightFeeder Pro?
Important
As FlightGazer is developed primarily as a personal project, it is currently not open to contributions.
Pull requests will be rejected.
Suggestions, comments, and bug reports are always welcomed and encouraged.
Additionally, word-of-mouth helps plenty! If you're already this far into the readme, spread the word!
If you'd like to make your own edits that changes the way the project operates, please fork this project.
If there's something not addressed here, please reach out to me directly.
- Another
dump1090xrgbmatrixproject, but renders out a minimap instead and uses larger RGB matrix panels- Fun fact: I used the same font from the above project for FlightGazer
- This All About Circuits Article from 2017
- Uses all the same core components that this project relies on at a surface-level: FlightAware's API (the older
Firehoseone),dump1090,rgbmatrix
- Uses all the same core components that this project relies on at a surface-level: FlightAware's API (the older
- Planefence, a logger for all the aircraft that flyby your location
- Inspired the base functionality of FlightGazer
- Skystats, a fancier way to show aircraft stats
- FlightGazer does aircraft stats via the log, but the above is a prettier way to see similar data (FlightGazer still tracks different aspects not covered by Skystats)
- MLB-LED-Scoreboard, instead of planes, track baseballs (another project that uses these RGB matrix panels)
* (dust) *
FlightGazer is licensed under the GPLv3 license.
In terms of warranty:
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
If you intend to use this project, the code must remain open source.
Huge shout out to RGBMatrixEmulator. This tool was invaluable for getting the layout dialed in and figuring out the logic needed to update the display correctly, all while avoiding having to program directly on the Raspberry Pi itself (VSCode Remote on a Zero 2W is literally impossible, I've tried).
^ Thanks to the fellow tech nerds in here for all the suggestions over the evolution of this project








