Restore the no-radio path with a configurable aggregator (#66) - #67
Open
ethanstoner wants to merge 1 commit into
Open
Restore the no-radio path with a configurable aggregator (#66)#67ethanstoner wants to merge 1 commit into
ethanstoner wants to merge 1 commit into
Conversation
airplanes.live went feeder-only. Its public endpoint now answers 403 with a
"contact us" body, so the api source - the whole point of "runs with no radio"
- is dead for every install that isn't feeding them, and so is the SFO ground
panel, which pinned the same host separately.
The provider was baked into two files and only overridable by an env var at
boot, so a user hit by this cannot fix it from the control panel. It is now a
config field beside radioUrl: live-editable, validated, persisted, and read on
every poll. Switching aggregators is one field and takes effect on the next
tick. sfo-ground.ts follows the same field instead of its own hardcoded URL,
so a dead host is one fix, not two.
The default moves to adsb.lol, which is free, needs no key, and serves the
same readsb JSON on the same /v2/point/{lat}/{lon}/{r} shape, so the
normalizer is unchanged. Verified live at SFO: 38 aircraft with routes and
types rendering on the display, and the ground panel populated.
One trap worth naming: adsb.lol 403s any request without a descriptive
User-Agent, including Node's default, so simply repointing the URL still
fails. Requests now identify Skylight the same way the geocoder already does
for Nominatim. Confirmed both ways - 403 without the header, 200 with it.
adsb.fi is documented as the alternative and verified end to end by switching
providers on a running server: it takes /lat/{lat}/lon/{lon}/dist/{r}, a
different path shape, which the existing template placeholders already cover.
That is why the whole URL is the unit of config rather than a provider name.
A 401/403 on the api source now says the aggregator refused the request and
points at the API URL setting, instead of reporting a bare "HTTP 403" that
reads like a bug in Skylight - the same misleading dead end the linked forum
thread describes. Rate-limit detection moved off string-matching the message
onto the status code carried by the error, so the cpaczek#24 backoff still fires.
Existing installs upgrade silently: config.json has no apiUrl, so the merge
supplies the new default. An explicit API_URL env still wins as a first-run
default, and a value already set in the panel wins over both.
Tests cover the config-driven URL, both provider path shapes, a live provider
switch, the User-Agent, the 403 guidance, and 429 backoff. Full suite: 198
passing, typecheck and build clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #66.
What's broken
api.airplanes.liveis feeder-only now. The public endpoint answers403with a "contact us" body:So the
apisource — the whole "runs with no radio" promise in the README — is dead for anyone who isn't feeding them.server/src/sfo-ground.tspinned the same host separately, so the "who's next" ground panel died with it.Four people are stacked in #66 asking the same question: is there another provider?
What this changes
The aggregator is now a config field, not a baked-in host.
apiUrlsits next toradioUrl: live-editable from the control panel's Source section, validated, persisted, and re-read on every poll. Switching provider is one field and applies on the next tick — no rebuild, no restart, no env var.sfo-ground.tsfollows the same field, so a dead host is one fix instead of two.The default moves to adsb.lol — free, no key, and it serves the same readsb JSON on the same
/v2/point/{lat}/{lon}/{r}shape, sonormalize()is untouched.One trap worth flagging: adsb.lol
403s any request without a descriptiveUser-Agent, including Node's default. Repointing the URL alone still fails — which is why this looked like the same 403 twice. Requests now identify Skylight the way the geocoder already does for Nominatim:Errors say what to do. A
401/403on theapisource now reads:instead of a bare
HTTP 403that reads like a bug in Skylight — the same misleading dead end the forum thread in #66 describes. Rate-limit detection moved off string-matching that message onto the status code carried by the error, so the #24 backoff still fires.Verified
Ran the server against the live API,
DATA_SOURCE=api, default config (SFO, 3 mi):UAL968 SFO→AMS,AFR83K SFO→CDG. Rendered on the display with runways, planets and trails./lat/{lat}/lon/{lon}/dist/{r}, a different path shape, which the existing placeholders already cover. That's why the whole URL is the unit of config rather than a provider name.POST /api/config {"apiUrl":"not a url"}→400 {"error":"apiUrl must be an http or https URL"}.pnpm typecheckandpnpm buildclean.New tests in
server/test/api-source.test.tscover the config-driven URL, both provider path shapes, a live provider switch, theUser-Agent, the 403 guidance, and 429 backoff.Upgrades
Existing installs fix themselves:
config.jsonhas noapiUrl, so the merge supplies the new default. An explicitAPI_URLenv still wins as a first-run default, and a value already set in the panel wins over both — same precedenceradioUrlhas.Notes
403/401, and anAPI_URLrow in the env table.