Skip to content

Add Label A9 DAI (Deliver ATIS Information) decoder plugin#410

Open
thepacket wants to merge 1 commit intoairframesio:masterfrom
thepacket:plugin/label-a9
Open

Add Label A9 DAI (Deliver ATIS Information) decoder plugin#410
thepacket wants to merge 1 commit intoairframesio:masterfrom
thepacket:plugin/label-a9

Conversation

@thepacket
Copy link
Copy Markdown

Adds a decoder for label A9 Deliver ATIS Information uplinks.

Handles three sub-formats:

  1. Proper D-ATIS reports: CYYZ ARR ATIS A 0800Z + METAR weather + INFORM ack
  2. NOTAM/closure fragments: taxiway closures, tower freq, HAZD WX area
  3. Crew-instruction messages: sub-label HPA= + ACKNOWLEDGE INFO R ON FIRST CTC WITH DELIVERY + .F465 flight ID

npm run build passes.

New plugin registered in official.ts and MessageDecoder.ts.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

Warning

Rate limit exceeded

@thepacket has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 55 minutes and 27 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 55 minutes and 27 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: cb83afec-8243-4d0b-ae01-dccfe2264ee7

📥 Commits

Reviewing files that changed from the base of the PR and between 10f9f69 and 8205655.

📒 Files selected for processing (3)
  • lib/MessageDecoder.ts
  • lib/plugins/Label_A9_DAI.ts
  • lib/plugins/official.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@kevinelliott kevinelliott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Adds Label_A9_DAI (593 lines) for D-ATIS uplinks: ATIS header, METAR-style weather, NOTAM-style closures (taxiway/runway/tower freq/hazard areas), and a crew-instruction sub-format with INFORM ATC INFO <letter> ack tokens. Registered in lib/MessageDecoder.ts and lib/plugins/official.ts. Build passes per the description.

Verdict

Needs changes before merge. The scope is impressive, but the file mixes three sub-formats with regex-only parsing that has no test coverage to back it up — and a couple of the field mappings are semantically incorrect.

Must Fix

  • No tests. A 593-line plugin with this many regex branches absolutely needs companion tests. Please add Label_A9_DAI.test.ts covering at least the three sub-formats called out in the PR description (proper D-ATIS, NOTAM/closure fragment, crew-instruction HPA= body). Use lib/plugins/Label_15.test.ts as a template.
  • raw.arrival_icao misuse. Line 86: decodeResult.raw.arrival_icao = airport;. The ATIS airport is not necessarily the aircraft's arrival airport — a pilot can pull D-ATIS for any field. Setting arrival_icao here will pollute downstream consumers that legitimately expect that field to mean "the destination of the flight". Drop that line and rely on atis_airport only. (For comparison, ResultFormatter.arrivalAirport() is also reserved for the actual flight destination and shouldn't be used here.)
  • HHMMZ time has no validation. Line 84: const hhmmZ = h[4] + 'Z';. There's no check that hours < 24 and minutes < 60, and the value is stored as a string "0800Z" instead of being normalized via DateTimeUtils.convertHHMMSSToTod like every other plugin in this repo. Either validate-and-normalize, or document why this plugin diverges from the convention.
  • Naming convention. routingPrefix (line 67), atis_airport, atis_letter, etc. mix camelCase and snake_case. The RawFields interface in lib/DecoderPluginInterface.ts uses snake_case throughout. Please rename routingPrefixrouting_prefix (and audit the rest of the plugin for similar drift).

Should Fix

  • Visibility regex is over-broad. Line 250: /\b(P?\d+(?:\s\d\/\d)?|\d\/\d)SM\b/ matches 15SM correctly, but the meter fallback at line 260 — /\b(\d{4})\s*(?:M|METRES?)?\b/ followed by a separate guard /\b\d{4}\s+(?:NDV|[A-Z]{2}V|[A-Z])/ — will happily eat a 4-digit clearance number, an altitude, or a frequency in any A9 body that isn't a clean METAR. Either anchor visibility to a METAR-style position (after wind, before sky) or skip non-SM visibility entirely until you have test fixtures proving the meters branch is needed.
  • Temp/dew regex collisions. Line 313: /\b(M?\d{1,2})\/(M?\d{1,2})\b(?!\d)/. This will fire on any "NN/NN" pattern inside the free text — e.g. fractional visibility "1 1/2", radio frequency suffixes, route segment labels. Please anchor to a position right after the altimeter/sky block, or require a leading whitespace boundary plus a known METAR neighbor token.
  • wind_direction raw type is string | number. Line 238: decodeResult.raw.wind_direction = wind[1] === 'VRB' ? 'VRB' : Number(wind[1]);. Mixing types in a single raw field is awkward to consume. Suggest either always-number with a separate wind_direction_variable: boolean, or always-string.
  • bird_hazard regex. Line 384: /\b([A-Z/ ]*BIRD[A-Z /]*ACT(?:IVITY)?[A-Z /]*)(?:\.|$)/. The leading [A-Z/ ]* will gladly walk back through several preceding words and capture them as the hazard string. Anchor to \bBIRD\b and capture only forward.
  • parseCrewInstruction operates on the un-stripped text. Line 149: this.parseCrewInstruction(text, decodeResult);. Every other parser uses remainingBody (post-routing-prefix). This means the routing-prefix path can leak into the sub_label / flight_id captures. Pass body or remainingBody for consistency.
  • atis_inform_suffix only set when present. Fine, but the suffix is rendered into the ATIS_ACK formatted value as (ref AB54B) — the "ref" prefix isn't standard ATIS terminology. Suggest rendering the letter and suffix joined: Info AB54B.

Nits

  • phonetic() could be a top-level constant Map/object — no need to instantiate every call.
  • coverName() likewise.
  • The descriptor "D-ATIS (Deliver ATIS Information) — ground-to-air uplink" already implies direction; the separate "Direction" row pushed in PR #409/#411 isn't pushed here, which is inconsistent across this contributor's PRs.
  • decoded is true if any of nine raw fields is set (line 180-191) — that's a bit broad. Even a stray INFORM token or a single closure match will mark the message decoded. Consider requiring at least one "header-class" signal (ATIS header, sub_label, or routing prefix) to claim full decoding.

Tests

Missing entirely. Minimum suggested fixtures (one of each from the PR description):

  • Proper D-ATIS: CYYZ ARR ATIS A 0800Z\n28008KT 15SM SCT060 CIG OVC140\n04/M01 A2992\n…
  • NOTAM fragment: TWY S CLSD BTN RWY 27R AND TWY D…
  • Crew instruction: HPA=\nACKNOWLEDGE INFO R ON FIRST CTC WITH DELIVERY\n.F465
  • Each variant should also exercise an empty-body and a totally-non-matching body to confirm the early returns.

Notes

  • Registration: confirmed in both lib/MessageDecoder.ts (line 81) and lib/plugins/official.ts (line 67) at the PR HEAD.
  • This plugin doesn't share the FANS 1/A envelope concerns from PRs #409/#411/#412, but the raw key naming convention should still align (snake_case).

Thanks @thepacket!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants