Skip to content

Expose route (origin/destination) as sensor attributes, not just via voice intents #4

Description

@Xenu-Ams

Bear with me, this is my first request ever.

Feature request: expose route (origin/destination) as sensor attributes, not just via voice intents

Summary

route_client.py already implements a working client for adsb.im's routeset API (POST https://adsb.im/api/0/routeset), and sensor.py already defines route_origin, route_origin_name, route_destination, and route_destination_name as attributes on the adsb_closest_aircraft sensor (and presumably the nearest-N sensor). However, tracing the actual call path shows that RouteClient is only ever invoked from intent.py, for voice/Assist queries (e.g. "what plane is that"). The coordinator that populates the aircraft dicts consumed by sensor.py never calls it — so those four attributes are always None in practice, even though the schema advertises them.

This means anyone trying to build a dashboard card or automation around route data (a very natural use case — "show me where this plane is going") currently gets nothing from the sensor itself, despite the plumbing being 90% there already.

Why this is worth fixing upstream

I worked around this with help in my own config with a separate rest_command + trigger-based template sensor that re-implements the same routeset call independently of the integration. It works, but it's a duplicate of logic that already exists in route_client.py, and every user hitting this gap has to rediscover and reimplement it themselves.

Suggested fix

Wire RouteClient into the coordinator's update cycle for the closest aircraft (and/or nearest-N) entries, with the same kind of debounce/caching this integration already does elsewhere for registration lookups, so route_origin/route_destination populate for real. A few implementation notes from building the workaround, in case useful:

  • Debounce on flight-number change, not on a fixed poll interval. Near a busy airport, the "closest aircraft" can change multiple times within 1–3 seconds; polling on a fixed timer (I initially tried 30s, then 10s) leads to routes lagging behind or applying to the wrong aircraft. Triggering specifically on a change to the flight attribute, with a short debounce (~2–3s) before firing the lookup, was much more reliable.
  • Distance threshold. No point spending a route lookup on aircraft far outside the area of interest — gating on distance_mi (or whatever the existing distance attribute is) below some threshold cuts a meaningful fraction of calls with no loss of relevant data.
  • Small per-callsign cache, even just the last ~15 entries, avoids redundant calls when the "closest aircraft" flaps between two aircraft at similar distance (common near airports) and repeatedly re-resolves the same callsign.
  • Quiet hours (optional/configurable) — for users who don't need overnight updates, an option to skip lookups during a configurable window would further cut API usage without any functional loss for the aircraft-count-focused audience of this integration.

Happy to share the exact template/config I used as a reference if that's useful, or to put together a PR if there's appetite for this — let me know which is preferred.

Context

  • Integration: hook-365/adsb-aircraft-tracker
  • Relevant files: coordinator.py, sensor.py, route_client.py, intent.py
  • Confirmed via source inspection that route_client.py's POST /api/0/routeset call format works correctly (tested directly with curl, returns valid _airports data) — the gap is purely that the coordinator never calls it.

Environment

  • Home Assistant OS, Core 2026.7.4, Supervisor 2026.07.5, OS 15.1, Frontend 20260624.6
  • Integration version: v1.4.2
  • ADSB feeder: adsb.im image (readsb/ultrafeeder + tar1090)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions