Tracking Flights in Home Assistant: DIY ADS-B Station with SDR & Docker

Have you ever looked out the window, heard a plane flying low, and wondered: “What plane is that, where is it going, and how high is it?”

By setting up a local ADS-B (Automatic Dependent Surveillance-Broadcast) receiver, you can track real-time flight data directly from the sky above your house. Even better, you can feed that data directly into Home Assistant for custom announcements, military aircraft detection, and live overhead maps!

Here is a high-level guide on how to build your own flight tracking station using a Raspberry Pi, an inexpensive SDR receiver, and the awesome Home Assistant integration adsb-aircraft-tracker.


:hammer_and_wrench: Hardware Requirements

You don’t need expensive equipment to get started. Here is the basic hardware stack:

  1. Single Board Computer: A Raspberry Pi 4 (or Pi 3) running Linux (Ubuntu Server or Raspberry Pi OS Lite).
  2. SDR Radio Receiver: An inexpensive RTL-SDR USB Dongle (such as the Nooelec RTL-SDR or RTL-SDR Blog V3/V4). This is the “radio” that listens to the 1090MHz signals broadcasted by aircraft.

:package: Software Stack: Docker to the Rescue

To decode the radio signals and broadcast them, the SDR-Enthusiasts community provides excellent, pre-configured Docker images. Running this in Docker keeps your Pi clean and updates simple.

Below is a generic docker-compose.yml to spin up the tracker (ultrafeeder which runs readsb to decode signals and generate a web map) and piaware (to feed data to FlightAware):

version: '3.8'

services:
  ultrafeeder:
    image: ghcr.io/sdr-enthusiasts/docker-adsb-ultrafeeder:latest
    container_name: ultrafeeder
    restart: always
    device_cgroup_rules:
      - 'c 189:* rmw' # Raw access to the USB SDR receiver
    ports:
      - "8080:80"       # Web interface map (HTTP)
      - "30005:30005"   # Raw data stream for Home Assistant
    environment:
      - TZ=America/New_York
      - LAT=YOUR_LATITUDE         # e.g., 40.7128
      - LONG=YOUR_LONGITUDE       # e.g., -74.0060
      - ALT=YOUR_ALTITUDE_IN_FEET # Antenna height above sea level
      - FEEDER_NAME=MyHomeTracker
      - READSB_AUTOGAIN=true      # Keeps signal gains tuned
    volumes:
      - /dev/bus/usb:/dev/bus/usb

  flightaware:
    image: ghcr.io/sdr-enthusiasts/docker-piaware:latest
    container_name: piaware
    restart: always
    device_cgroup_rules:
      - 'c 189:* rmw'
    environment:
      - TZ=America/New_York
      - PIAWARE_RECEIVER_TYPE=relay
      - PIAWARE_RECEIVER_HOST=ultrafeeder
      - PIAWARE_RECEIVER_PORT=30005
      - PIAWARE_FEEDER_ID=YOUR_FLIGHTAWARE_FEEDER_ID # Lock in your Feeder ID here after first run
    volumes:
      - /dev/bus/usb:/dev/bus/usb

[!TIP]
Claim a Free $90/Month Enterprise Account!
Once your Pi is feeding data to FlightAware, log in to FlightAware from a computer on the same network and visit the PiAware Claim Page. Claiming your station automatically unlocks their top-tier Enterprise Account for free as long as your feed remains active!


:house_with_garden: Integrating with Home Assistant

While you can query the raw JSON feeds via native REST sensors, using a dedicated integration is much more powerful.

I used the adsb-aircraft-tracker integration (available via HACS) to bring everything into Home Assistant. It was exactly what I was looking for (thanks hook-365 for all the cool ideas and examples).

Key Features of the Integration:

  • Real-time closest aircraft monitoring: Pulls direct distance (miles) and altitude (feet) for the aircraft nearest to your home.
  • Specialized sensors: Tracks overall overhead aircraft count, custom altitude boundaries, and military aircraft presence.
  • Custom Sentences / Assist integration: Allows you to ask your voice assistant “What’s flying overhead?” or “What plane is that?” and get spoken answers.

High-Visibility Dashboard Setup

With the integration running, you can set up a beautiful Flight Radar section on your Lovelace dashboard:

  • Military Aircraft Alert Card: A conditional card at the top of your dashboard that flashes a high-visibility alert only when a military aircraft is detected nearby, complete with a callsign and aircraft type summary.
  • Live Web Map Integration: Use an webpage card to embed the live Ultrafeeder map (http://your-pi-ip:8080/) for a real-time, interactive radar display directly inside your dashboard.
  • Aircraft Count Gauge: A simple gauge mapped to a template sensor tracking active overhead aircraft count.

:robot: Cool Automation Ideas

Here are two awesome automations you can build using the entities created by the integration:

1. Military Aircraft Presence Alert

Get notified instantly on your phone when a military aircraft enters your airspace.

alias: "Military Aircraft Detection"
trigger:
  - platform: state
    entity_id: binary_sensor.adsb_tracker_military_aircraft_present
    from: "off"
    to: "on"
action:
  - service: persistent_notification.create
    data:
      title: "Military Aircraft Detected"
      message: "{{ state_attr('sensor.adsb_tracker_military_aircraft_details', 'summary') }}"

2. Proximity Voice Announcements

Have your smart speakers announce low-flying aircraft overhead during the day:

alias: "Aircraft Overhead Announcement"
trigger:
  - platform: numeric_state
    entity_id: sensor.adsb_tracker_closest_aircraft
    attribute: distance_mi
    below: 2
condition:
  - condition: numeric_state
    entity_id: sensor.adsb_tracker_closest_aircraft
    attribute: altitude_ft
    below: 3000
  - condition: time
    after: "08:00:00"
    before: "22:00:00"
action:
  - service: tts.speak
    target:
      entity_id: tts.google_en_com # or your preferred TTS service
    data:
      media_player_entity_id: media_player.living_room_speaker
      message: >-
        {% set tail = state_attr("sensor.adsb_tracker_closest_aircraft", "tail") %}
        {% set altitude = state_attr("sensor.adsb_tracker_closest_aircraft", "altitude_ft") %}
        {% if tail and tail | trim != "" and tail != "Unknown" %}
          Aircraft {{ tail }} is overhead at {{ altitude }} feet.
        {% else %}
          An unidentified aircraft is overhead at {{ altitude }} feet.
        {% endif %}

:memo: Tips & Lessons Learned

  • Coordinate Mapping: Make sure to map environment coordinates using LAT and LONG inside your Docker Compose rather than outdated variables, which ensures the local readsb instance populates flight distances accurately inside the generated aircraft.json for Home Assistant.

In times of heightened alert, do military aircraft transmit ADS-B traffic data de-codeable on civilian receivers? My understanding is their ‘normal’ ADS-B disappears and military ATC co-ordinated with civilian ATC for spatial awareness and traffic routing.

What does this app, you have generously contributed building on the shoulders of giants, offer above and beyond the FlightRadar24 app already available in HACS? Can I run both at the same time? Will there be any conflicts or overlap? Is the data your personal ADSB receiver collects not good enough to use direct in your app, and has to be sourced from feeders on the cloud you have possibly contributed to, a roundabout trip that has dependencies a local solution may not have?

The hardware (Pi with dongle and antenna) used to be free too, but it seems most airports are covered, and the “free data” you are not only accessing, but contributing to is making a lot of money for somebody else. See the discussion here:

I’m not sure if the community is aware of that.

1 Like

Yeah I applied for a free one and the area was already covered. I could have used flight radars integration, but like local when I can. I also had a spare RPI and an SDR that was underutilized in my home lab. I found it a fun project to do it local. I’m sure you could run it next to another flight service. I did not install Flight Radar’s integration, so I don’t have a comparison. I’m still figuring out how military aircraft are handled…