Custom Component: Flightradar24

The bug with device tracker was fixed
Yes, after integration reload or Home Assistant restart - The airport field clears

2 Likes

Any reason we don’t keep it like the additional tracked? That means if I want to track a home airport I need to automate that on every HA restart?

Thank You for the fix!

1 Like

It would require more time to develop this new airport tracking feature. It is in my plan for next releases

v1.31.0 Released

Changelog

3 Likes

v1.31.1 Released

Changelog

This is a great custom component. I have an automation that provides an alert when a airplane enters the area which works fine. I would like to modify this for certain conditions e.g. low altitude, particular flights. I have added the following as a condition in the automation:

condition: template
value_template: '{{ trigger.event.data.altitude < 10000 }}'

or:

condition: template
value_template: '{{ trigger.event.data.aircraft_registration == ''G-ABCD'' }}'

…but when they are triggered, I get the following error message:

Error: In 'template' condition: UndefinedError: 'dict object' has no attribute 'event'

Grateful for any pointers on what I’m doing wrong. Thanks.

Hi everyone, I’m excited to try to get this working but I’m not having a lot of luck with the airport I am trying to monitor - It might be me!

The airport is ā€˜OOL - Gold Coast Airport, Australia’

Only 4 sensors are available and they are working ok.
Is it a local config issue that I am not seeing the arrivals and departures information in HA? (Which is showing ok on Flightradar24).
Thanks.

I didn’t really like the simple markdown output for the flight information, it felt a bit messy and hard to read.

So instead I used a conditional card together with tailwindcss-template-card to render a small airport-style board. The conditional card hides the board when there are no flights, and the template card makes it possible to build a cleaner layout with columns (time, flight, from, to, status).

This way the card stays compact and looks a bit more like a real arrival/departure display.

type: vertical-stack
cards:
  - type: iframe
    url: >-
      https://globe.adsb.fi/?enableLabels&trackLabels&zoom=7&hideSideBar&lat=63.26674861441635&lon=13.243913920819967&hideButtons
    aspect_ratio: 100%
    hide_background: true
    card_mod:
      style: |
        ha-card {
          aspect-ratio: 16 / 9;
        }
  - type: conditional
    conditions:
      - condition: numeric_state
        entity: sensor.flightradar24_current_in_area
        above: 0
    card:
      type: custom:tailwindcss-template-card
      entity: sensor.flightradar24_current_in_area
      content: >
        {% set flights =
        state_attr('sensor.flightradar24_current_in_area','flights') |
        default([], true) %}

        <div class="rounded-2xl border border-white/10 bg-[rgba(6,10,14,0.92)]
        p-3 font-mono shadow-[0_10px_30px_rgba(0,0,0,0.35)]">

          <div class="mb-3 flex items-center justify-between border-b border-[#24303d] pb-2">
            <div class="text-[11px] uppercase tracking-[0.28em] text-[#8ea0b3]">
              Air Board
            </div>
            <div class="text-[11px] uppercase tracking-[0.22em] text-[#ffd36a]">
              Live traffic
            </div>
          </div>

          <div class="grid grid-cols-[72px_88px_minmax(0,1fr)_minmax(0,1fr)_92px] gap-x-3 px-2 pb-2 text-[10px] uppercase tracking-[0.22em] text-[#6f8092]">
            <div>Time</div>
            <div>Flight</div>
            <div>From</div>
            <div>To</div>
            <div>Status</div>
          </div>

          <div class="flex flex-col gap-1.5">

            {% for f in flights[:5] %}
              {% set dep = f.time_scheduled_departure | timestamp_custom('%H:%M') if f.time_scheduled_departure else '--:--' %}
              {% set alt = f.altitude | int(0) %}
              {% set spd = f.ground_speed | int(0) %}

              {% if alt > 30000 %}
                {% set status = 'CRUISE' %}
              {% elif alt > 0 %}
                {% set status = 'AIRBORNE' %}
              {% elif spd > 30 %}
                {% set status = 'TAXIING' %}
              {% else %}
                {% set status = 'SCHEDULED' %}
              {% endif %}

              <div class="grid grid-cols-[72px_88px_minmax(0,1fr)_minmax(0,1fr)_92px] items-center gap-x-3 rounded-lg border border-[#1d2630] bg-[linear-gradient(180deg,rgba(18,24,32,0.98),rgba(10,14,20,0.98))] px-2 py-2 text-[13px] shadow-[inset_0_1px_0_rgba(255,255,255,0.03)]">

                <div class="truncate text-[#f2f5f7]">
                  {{ dep }}
                </div>

                <div class="min-w-0">
                  <div class="truncate font-semibold tracking-wide text-[#ffd36a]">
                    {{ f.flight_number or f.callsign or 'UNKNOWN' }}
                  </div>
                  {% if f.airline_short %}
                    <div class="truncate text-[10px] uppercase tracking-[0.16em] text-[#7f90a1]">
                      {{ f.airline_short }}
                    </div>
                  {% endif %}
                </div>

                <div class="truncate text-[#f2f5f7]">
                  {{ f.airport_origin_city or '?' }}
                </div>

                <div class="truncate text-[#f2f5f7]">
                  {{ f.airport_destination_city or '?' }}
                </div>

                <div class="truncate text-right font-semibold
                  {% if status == 'CRUISE' %}
                    text-sky-300
                  {% elif status == 'AIRBORNE' %}
                    text-[#ffd36a]
                  {% elif status == 'TAXIING' %}
                    text-orange-300
                  {% else %}
                    text-[#8ea0b3]
                  {% endif %}
                ">
                  {{ status }}
                </div>

              </div>
            {% endfor %}

          </div>
        </div>
grid_options:
  columns: 15
  rows: auto

3 Likes

thats amazing! thank you!!

yea. I, too, see those exact unavailable. I installed FT awhile back and not really looked at all the sensors.

ok. figured it out. In the FT24 integration page where you see configuration, you need to input the airport code (IATA or ICAO) of the airport you want to track like so below. If you have trouble finding this tab, you can search for sensor text.flightradar24_airport_track and input the airport code.

I’m trying to filter the airline name where if it does not show its name to output some text. However, it doesn’t work for. Me. The output states None for the airline name.

I have tried to filter for None, none, unknown, Unknown.

Sharing your code to show what you’ve tried would help. I assume you’re looking for something like this:

{% if flight.flight_number != None %}{{ flight.flight_number }} 
{% if flight.flight_number != flight.callsign %}({{ flight.callsign }}){% endif %}
 - {{ flight.airline_short }} - {{ flight.aircraft_model }}
{% else %}
{{ flight.callsign }} - {{ flight.aircraft_model }}
{% endif %}

In this case, if the flight_number is none, only the callsign and aircraft_model is displayed. Otherwise, the flight_number, callsign (if it doesn’t match the flight_number), arline_short and aircraft_model are displayed.

This is my ā€œFlightradarā€ card. It uses a custom:stack-in-card with a little bit of card_mod. The Markdown card uses table HTML instead of table Markdown. Setting its max-height in card_mod allows the overflow to scroll. I also set it to not show US flags, but it will show flags from other countries along with the name.

YAML Code
type: custom:stack-in-card
cards:
  - type: markdown
    content: |
      <center><font size="5">Flightradar24
      <center><font size="2">{{states('sensor.flightradar24_current_in_area')}}
      aircraft in the area
    card_mod:
      style: |
        ha-card {
          margin-top: -10px !important;
          margin-bottom: -20px !important;
        }
  - type: iframe
    url: "https://globe.adsb.fi/?enableLabels&trackLabels&zoom=11&hideSideBar&lat=39.99&lon=-83.01"
    aspect_ratio: 100%
  - type: conditional
    conditions:
      - condition: numeric_state
        entity: sensor.flightradar24_current_in_area
        above: 0
    card:
      type: markdown
      content: >-
        {% set data = state_attr('sensor.flightradar24_current_in_area','flights') | default([], true) %} 
        {% for flight in data %}
          <table width="100%"> 
          <tr><center><ha-icon icon="mdi:airplane"></ha-icon>{% if flight.flight_number != None %}{{ flight.flight_number }} {% if flight.flight_number != flight.callsign %}({{ flight.callsign }}){% endif %} - {{ flight.airline_short }} - {{ flight.aircraft_model }}{% else %}{{ flight.callsign }} - {{ flight.aircraft_model }}{% endif %}</tr>
          <tr><th><center>Departure</th><th><center>Destination</th><th><center>Altitude</th><th><center>Ground Speed</th></center></tr>
          <tr>
            <td align="center" valign="top">{% if flight.airport_origin_city %}{{ flight.airport_origin_city }}{% if (flight.airport_origin_country_code and flight.airport_origin_country_code != "US") %}<img src="https://flagsapi.com/{{ flight.airport_origin_country_code }}/shiny/16.png" title='{{ flight.airport_origin_country_name }}'/>{% endif %}{% endif %}
              {%if flight.time_scheduled_departure %}<br>{{ flight.time_scheduled_departure | timestamp_custom('%H:%M') }}{% endif %}</td>
            <td align="center" valign="top">{% if flight.airport_destination_city %}{{ flight.airport_destination_city }}{% if (flight.airport_destination_country_code and flight.airport_destination_country_code != "US") %}, {{airport_destination_country_name}}<img src="https://flagsapi.com/{{ flight.airport_destination_country_code }}/shiny/16.png" title='{{ flight.airport_destination_country_name }}'/>{% endif %}{% endif %}
              {% if flight.time_scheduled_arrival %}<br>{{ flight.time_scheduled_arrival | timestamp_custom('%H:%M') }}{% endif %}</td>
            <td align="center" valign="top">{{ flight.altitude }} ft</td>
            <td align="center" valign="top">{{ flight.ground_speed }} kts</td>
          </tr>
          </table><br>
        {% endfor %}
      card_mod:
        style: |
          ha-card {
            margin-top: -10px !important;
            margin-bottom: -20px !important;
            --markdown-table-border-color: transparent;
            max-height: 340px
          }

EDIT: Updated URL to include some extra options such as kiosk mode and settings brightness and contrast.

old image

1 Like

Hi. Thanks for the reply. I have choose action automation that sends me text messages of any aircraft that fly above my area. Occasionally, there will be government aircraft with no flight plan or call sign, When that is the case, I just wanted a generic text like below. However, it is not catching the None or Private Owner

  - alias: 'Flight entry notification'
    triggers:
      - trigger: event
        event_type: flightradar24_entry
    conditions: []
    actions:
      - choose:
          - conditions:
              - condition: template
                value_template: "{{ trigger.event.data.airline | lower | regex_search('null|unknown|private owner|honda airways|none') }}"
            sequence:
              - action: script.text_notify
                data:
                  who: amber
                  message: >-
                    ā€¼ļø No flight plan. The aircraft is either private or goverment operated.										
.
.
.

The problem you are running into is null and None are not actually strings; they’re data types. Your template needs to check for check that data type and the specific strings.

{{ trigger.event.data.airline is undefined 
or trigger.event.data.airline | lower | regex_search('unknown|private owner|honda airways')
}}

This should work for you. I noticed when I was testing this that it did catch N4836G as a Private Owner.

You might consider expanding your template to check for an undefined flight_plan too (but also consider filtering out on_ground as I’ve noticed planes that have not taken off or started taxiing will sometimes not have a flight plan shown at the time.) Most of the aircraft without flight plans I notice in my are are either police helicopters and MedEvac flights but they do have an airline listed. You can string together OR, AND, and NOT to get your template to test for various conditions.

For working with data types, you can use is defined, is not defined, is undefined, and is not undefined. You can also be more specific with is none and is not none, for example.

Here’s an example of a medevac flight with no flight number but there is an airline listed.

flight_number: null
callsign: N942CF
aircraft_registration: N942CF
aircraft_model: Leonardo AW169
aircraft_code: A169
airline: Premier Health CareFlight
1 Like

v1.32.0 Released

Changelog

seems broken - since 30-apr-2026.

2 Likes

Confirming appears broken for me also since 30th April

1 Like

This GitHub issue 403 Forbidden on `clickhandler` endpoint Ā· Issue #201 Ā· AlexandrErohin/home-assistant-flightradar24 Ā· GitHub has details on the issue and a workaround for the change in the Flightradar24 API at end April 26…

FYI @arjunprabhu @Tes8080

Having the same issue. Only 4 sensors available. I’ve added my airport in the configuration panel. I’ve tried both codes. upper case, lower case. Nothing seems to work. I reloaded the integration, but still nothing. What’s the trick here?

I’m on v1.32