Skip to content

FlightGazer, a program to show dump1090 info to an RGB-Matrix display.

Notifications You must be signed in to change notification settings

WeegeeNumbuh1/FlightGazer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

14 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Logo

FlightGazer

A program to show dump1090 ADS-B info to an RGB-Matrix display.

๐Ÿšฉ About

This is a personal project that was heavily inspired by Colin Waddell's project, but supplements flight information of nearby planes with real-time ADS-B and UAT data from dump1090 and dump978. Uses the FlightAware API instead of FlightRadar24 to get a plane'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).

As usual, this project was developed before being tracked by git. :gladsuna:

๐Ÿ‘€ What it looks like

Show/Hide images

When a plane enters the area...

...and once it leaves.

Handles multiple planes in the area...

...and moments when the API takes its time.

Handles even odd edge cases like this.
Neat ๐Ÿ‘

๐Ÿ’ช Features

  • Visualize and figure out what planes are flying nearby your location, in a cool-looking way!
    • Shows a plane's callsign (or registration as fallback), distance and direction from your location, the plane'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 plane has been flying
    • If you don't want to use the API, there's an available "Enhanced Readout" mode that shows even more plane info from dump1090, such as latitude, longitude, ground track, vertical speed, and RSSI
  • It's a neat looking clock when there aren't any planes flying overhead
    • When dump1090 is running, shows overall stats like how many planes you're tracking at the moment, how many planes flew by today, and the furthest plane you can detect
  • Automatically switches to other plane(s) if more than one is within the area
  • Fully Python based
    • The python script has been verified to run in both Linux (Debian) and Windows
  • Does not need to run on the same hardware that dump1090 is running from
  • Reads dump978 data if it's present as well
  • Customizable features such as:
    • Range of which planes need to be in for detailed tracking
    • Height filtering
    • Units (aeronautical, metric, or imperial)
    • Clock style (12 hour or 24 hour)
    • ๐Ÿ†• Brightness based on time of day or when there's an active plane shown
    • ๐Ÿ†• Display sunrise and sunset times or detailed signal stats for your dump1090 receiver
    • Writing to a stats file that keeps count of number of planes flying by per day (and API usage as well)
    • API limiting per day (those API calls can get expensive)
  • Can emulate an RGB Matrix display in a browser if you don't have the actual hardware
  • Detailed console output when run interactively
  • Small memory footprint
  • 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
  • Can be configured to run automatically inside tmux
  • ๐Ÿ†• Tested to work with Ultrafeeder and ADSB.im setups

๐Ÿ› ๏ธ Setup

โš ๏ธ Prerequisites

Show/Hide

Using this project assumes you have the following:

MINIMUM

  • A working dump1090 instance or similar where /data/aircraft.json can be read
    • Ex: tar1090, piaware/skyaware, dump1090-fa, dump1090-mutability, and readsb
      • 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 dump1090 is running from (see Configuration section)
  • Python 3.8 or newer
  • A working internet connection for setup
  • for Linux distros:
    • ssh access if running headless
    • apt as the package manager
    • Root access (necessary for accessing the RGBMatrix hardware)
    • systemd based system

Highly Recommmended

  • The rgbmatrix library installed and present on the system
    • Refer to adafruit's guide on how to get this working if it's not installed already
    • rgbmatrix does not need to be strictly installed to run this script (see Usage section)
  • The physical RGB matrix hardware (again, not strictly necessary)
    • a 32x64 sized matrix display (this is the only layout this script was designed for)
  • Your location set in dump1090

For Enhanced Functionality

  • A FlightAware API key (optional) for getting additional plane information such as origin/destination airports
  • RGBMatrixEmulator (optional, installed by default when using the initalization script) for emulating the display output if you don't have the physical hardware or just want to see the output in a web browser
  • a running dump978 instance if you're in the US and live near airports that handle general aviation more than commercial flights

๐Ÿ“ถ Installation & Getting Started

Make sure you meet the above prerequisites. To begin:

git clone --depth 1 https://github.com/WeegeeNumbuh1/FlightGazer

Note

Once the above command is completed, it is recommended to configure your setup now before running the initalization file. See the Configuration section below, then return to this step.

if running Linux (Debian) / Raspberry Pi

then run the following:

sudo bash FlightGazer/FlightGazer-init.sh

which will set up everything needed to run FlightGazer and then will start FlightGazer afterwards. (Click here to view what the init.sh file does)

if running Windows

You will need to put in some elbow grease here.

[!IMPORTANT] You're likely not going to be running rgbmatrix on Windows. Instead, use RGBMatrixEmulator.

pip install psutil
python3 -m venv --system-site-packages "\path\to\new-python-venv"
cd "\path\to\new-python-venv\Scripts"
pip install requests
pip install pydispatcher
pip install schedule
pip install RGBMatrixEmulator

If 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.

๐ŸŽš๏ธ Configuration

The config.py file is where settings are configured. It has descriptions/explanations for all configurable options. It is found (and needs to be) in the same directory as the main script itself. Edit it as needed before running FlightGazer.

Note

If the configuration file is missing or has invalid values, the main script has built-in fallbacks. It will alert you as necessary.

Configuration details for a remote dump1090 installation

Set CUSTOM_DUMP1090_LOCATION to the IP address of the device running dump1090.
Example: http://192.168.xxx.xxx:8080


Tip

To reduce flickering on a physical RGB matrix display, do the following:

๐Ÿƒโ€โ™‚๏ธ Usage

The main python script (FlightGazer.py) is designed to be started by the FlightGazer-init.sh file.

Important

By default, the script is designed to run at boot (via systemd with flightgazer.service). You can check its status with:

sudo systemctl status flightgazer.service
# or
sudo tmux attach -d -t FlightGazer

โš™๏ธ Interactive Mode

However, the script and python file are also designed to run interactively in a console. If you run the following command manually:

sudo path/to/FlightGazer/FlightGazer-init.sh

The script automatically detects that you're running interactively and will display realtime output, like so:

Example output
===== FlightGazer Console Output ===== Time now: 2024-12-01 00:00:00 | Runtime: 98 days, 23:48:05
Filters enabled: <60nmi, <15000ft
(* indicates in focus, - indicates focused previously)
[Inside focus loop 64, next switch on loop 75, watching: 'aa3ae5']

Plane scratchpad: {'aa3ae5', 'a10d75'}
*   [001] UAL343   (US, aa3ae5) | SPD: 263.1kt @ 288.8ยฐ | ALT:  8225.0ft,  3520.0ft/min | DIST: NW 22.4nmi (4x.005, -8x.192) | RSSI:  -8.2dBFS
  - [002] N167UD   (US, a10d75) | SPD:  58.7kt @ 283.8ยฐ | ALT:  1100.0ft,     0.0ft/min | DIST: E  53.2nmi (4x.985, -8x.078) | RSSI: -23.2dBFS

API results for UAL343: ORD -> SFO, 0:24 flight time

> dump1090 response 28.107 ms | Processing 3.223 ms | Display formatting 0.279 ms | Last API response 349.265 ms
> Detected 154 plane(s), 2 plane(s) in range, max range: 177.2nmi | Gain: 40.2dB, noise: -34.6dB, strong signals: 3.4%
> API stats for today: 13 success, 0 fail, 0 no data, 0 cache hits
> Total flybys today: 13
> CPU & memory usage: 16.925% overall CPU | 7.734MiB

๐Ÿ”ก Optional Behaviors

FlightGazer-init.sh supports optional arguments that adjust the behavior of the 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 Is
interactive?
What it does
(no flag) โŒ Default operating mode when not run as a service. Minimizes console output.
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 Tip below)
-f โœ… No Filter mode.
Ignores set RANGE and HEIGHT_LIMIT settings and shows all planes detected.
Display will never show plane 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.
-h โœ… Print the help message.

Tip

An important one is -e, which switches the display renderer from rgbmatrix to RGBMatrixEmulator. This is useful in case you are not able to run the display output on physical hardware and is the fallback when actual hardware is not available.
By default, RGBMatrixEmulator can be viewed through a web browser: http://ip-address-of-device-running-FlightGazer:8888

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 the same arguments as the initialization script, but you can always pass -h to see all possible operating modes.

๐Ÿ‘“ Misc

What the initialization script does
  • Checks if there is an internet connection
  • Checks if first_run_complete exists
    • Checks last modified date: if greater than a month, 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
    • python3-venv
    • tmux
  • Create a new systemd service flightgazer.service
  • Write out RGBMatrixEmulator config file
  • Makes virtual python environment at etc/FlightGazer-pyvenv
  • Updates pip as necessary and installs the following python packages in the virtual environment:
    • requests
    • pydispatcher
    • schedule
    • psutil (usually provided in Raspberry Pi OS)
    • suntime
    • RGBMatrixEmulator
  • Writes first_run_complete blank file to etc/FlightGazer-pyvenv to show initial setup is done
Running on Windows

No fancy initialization script here. 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 all FlightGazer-related processes (Linux):

kill -15 $(ps aux | grep '[F]lightGazer.py' | awk '{print $2}')

Changing systemd startup command

sudo nano /etc/systemd/system/flightgazer.service
systemctl daemon-reload

๐Ÿšฎ Uninstall

sudo bash /path/to/FlightGazer/uninstall.sh
Windows

Simply delete the folder (and the virtual python environment if you set that up as well).

โ” Frequently Asked Questions (not really but they could pop up)

FAQ's

Q: My RGB display is blank when running this, what broke?
A: Check the HAT_PWM_ENABLED value in config.py and make sure it matches your hardware setup.

Q: Can I customize the colors?
A: Sure, just edit them in the script. (Check the functions inside the Display class in the main python file)

Q: Can I customize the layout beyond what can be done in config.py (clock, plane info, etc)?
A: Sure, just like the last question, change some things in the script. :gladsuna:

Q: What about showing other plane info like what airline it is or what kind of plane it is?
A: That requires additional API calls or another API entirely. Plus, to put all possible text would require scrolling which would complicate things further (I did not feel like I needed this info).
You can also use Planefence for this functionality.

Q: Why use the FlightAware API? Why not something more "free" like adsbdb?
A: adsbdb only has reported route information for aircraft that have predetermined origins and destinations. In my experience, it cannot handle position-only flights (i.e. general aviation, military, etc) and is lacking information for some flights. The commercial APIs handle these situations much more elegantly (which is the price to pay, I guess). Moreover, FlightAware's API is the only commercial one that has a usable free tier. I do wish FlightAware had a much lighter API call for pulling very basic information like what this project uses.

Q: Some of your code is not pythonic!!!1!!111
A: but it works, does it not?

๐Ÿ› Known Issues and Shortcomings

Show/Hide
  • Flyby stats are not 100% accurate (but can be close, depending on your FLYBY_STALENESS setting in config.py)

    • This stat relies on the number of unique planes seen, not each occurence of an actual flyby
      • This is somewhat by design, covering the case of living near a general aviation airport and having the same plane do numerous touch-and-go landings
    • For example, if plane with hex ID abcdef passes by at 06:00, then passes by again at 18:00, it won't count as a flyby
      This has been fixed in v.1.3.0 with the addition of a new parameter, FLYBY_STALENESS
  • If using No Filter mode and restarting FlightGazer often, we can artifically inflate the flyby count

    • FlightGazer has a feature where it will write out stats before shutting down so that it can reload those stats upon restart (if it's the same day). The flyby count is simply a number and has no additional information such as the IDs of planes
    • Upon reload, FlightGazer fills in dummy IDs equal to the value of the last written flyby count in its internal list of plane IDs it keeps track of for flybys
    • The flyby count runs under the assumption that the flyby area itself is small, but since No Filter removes that restriction, it's a free-for-all
    • This is not usually a problem, as long as we don't restart often in the same day
    • May not ever get fixed

Found a bug? Want to suggest a new feature? Open an issue here on Github.

โœ๏ธ Changelog & Planned Features

Read: Changelog.txt.

Faraway ideas:

  • Brightness changing
  • Docker image?
  • Settings management from webpage?

๐Ÿ“– Additional Related/Similar Projects

  • Another dump1090 x rgbmatrix project, 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 Firehose one), dump1090, rgbmatrix
  • Planefence, a logger for all the planes that flyby your location
    • Inspired the functionality of the stats file FlightGazer writes out

โœ… Acknowledgements

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).

soootrue

^ Thanks to the fellow tech nerds in here for all the suggestions over the evolution of this project