victorchandra-devandClaude Opus 5.5 2dcf76fc0b Add the full v1 flight lifecycle, X-Plane auto-discovery and a FlyWithLua feed
Flight lifecycle (README §4-§7):
- Start, resume, finish, cancel and abandon sessions; destructive actions confirm first
- Telemetry recorded at 1 Hz to a per-session disk queue (fsync before queued,
  removed only after the server acks), batched uploads with 5/10/20/40/60 s
  backoff, Retry-After, and no retry on 4xx; server score and phase shown live
- Pre-flight checklist: X-Plane live, position, aircraft type, departure radius,
  on ground, flight level, route, runways; SimBrief OFP import
- App Nap and idle sleep held off while recording; resume after quit or crash

X-Plane:
- Unconnected loopback UDP (X-Plane replies from its send port)
- Finds X-Plane's receive port from its BECN beacon or X-Plane.prf; manual override
- Aircraft identity via string datarefs; token-based aircraft type check
- Datarefs verified against X-Plane 12.4.3; NaN/inf dropped; ground-speed
  multiplier counted in simRate; engines 3-4; transponder clamped to 0-5

FlyWithLua (optional second feed):
- Settings tab installs a generated Sigantara_ACARS.lua that writes the same
  datarefs to Output/sigantara_acars_feed.json each second; verified live

Also: local diagnostic log with consented upload, release script for
Developer ID signing and notarization, two adversarial review rounds applied,
92 tests against a stub server and a fake X-Plane (never production).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 15:53:00 +07:00

Sigantara ACARS — macOS

SwiftUI client for the Sigantara ACARS API. Contract: docs/acars-macos/README.md and openapi.yaml (v0.8.31).

Requirements: Xcode 27+, macOS 14+. No third-party dependencies.

open SigantaraAcars.xcodeproj
xcodebuild test -project SigantaraAcars.xcodeproj -scheme SigantaraAcars -destination 'platform=macOS'

Layout (MVVM)

Folder Contents
SigantaraAcars/Models Codable mirror of the OpenAPI schemas
SigantaraAcars/Services APIClient (+ retry rules, request log), Keychain, DeepLink, XPlane (RREF/DREF codec, conversions), XPlaneLink (live UDP link), AircraftCheck, FlightStore (disk queue), AppLog
SigantaraAcars/ViewModels AppModel (auth, deep links), DashboardModel (bid, weather, news, logbook), FlightModel (session lifecycle, recording, upload), Preflight (start checklist)
SigantaraAcars/Views SwiftUI screens; Theme holds the sigantara.com tokens
Config/Info.plist sigantara-acars:// URL scheme (merged with generated plist)
scripts/release.sh Developer ID sign, notarize, staple, zip

The project uses synchronized folders: new files dropped into SigantaraAcars/ or SigantaraAcarsTests/ are picked up without editing the project.

Flying with it

  1. Start X-Plane 11 or 12 and load the booked aircraft at the departure gate. ACARS connects by itself; nothing to set up in either app (see Finding X-Plane).
  2. Flight → Pre-flight: optionally Import from SimBrief (set your SimBrief Pilot ID in Settings), check the cruise level and route, and wait for every check to be green: X-Plane live, position received, aircraft type matches the booking, within the server's departure radius, on the ground.
  3. Start flight. ACARS records one sample per second to disk and uploads batches of about 15. The server's phase and score show in the flight card; uploads retry with 5/10/20/40/60 s backoff when offline, and nothing is lost on a force-quit.
  4. After landing and parking: Finish flight. ACARS uploads everything queued, then files the PIREP. If the server refuses (for example "landing not detected"), the flight keeps recording.
  5. Cancel flight and Abandon (for a session still open on the server) ask first: both are destructive.

Finding X-Plane

X-Plane's receive port is a user setting (49000 by default; it can be anything). ACARS never assumes it:

  1. Beacon: X-Plane multicasts a BECN packet about once a second (239.255.1.1:49707) carrying its receive port. ACARS follows it, from this Mac only. macOS asks once for Local Network access.
  2. Preferences: before a beacon arrives, or if that access is denied, ACARS reads _rcv_port from the running X-Plane's Output/preferences/X-Plane.prf (and notices _disable_incoming_networking).
  3. Manual port in Settings, for setups with the beacon turned off.

Data requests and replies use loopback only. X-Plane replies from its send port, so the socket is unconnected on purpose.

Optional: FlyWithLua feed

With FlyWithLua NG+ installed in X-Plane, Settings → FlyWithLua → Install ACARS Script writes Sigantara_ACARS.lua into X-Plane/Resources/plugins/FlyWithLua/Scripts/. Then choose Plugins → FlyWithLua → Reload all Lua script files in X-Plane. The script binds the same datarefs as UDP (it's generated from XPlane.DataRef), writes them once a second to X-Plane/Output/sigantara_acars_feed.json (temp file + rename), and removes the file when Lua stops. ACARS uses whichever feed is fresh and prefers FlyWithLua; the Simulator card says which one is in use. UDP needs nothing installed and stays the default.

Aircraft type check

X-Plane's acf_ICAO and acf_ui_name are compared with the booking's aircraft (and expectedAircraftTitle when the server sends it) as token lists, runs of letters and digits ("Boeing 737-800" is BOEING · 737 · 800), one appearing whole inside the other. A known ICAO designator decides first via a table of the model names bookings use, and the code itself only counts on an exact match. Variants pass (A320neo for A320, 777-300ER for 777-300); different types block the start (737 MAX for 737-800, 737-700 for B737-800, A330-900 for A330-300). If X-Plane reports neither string, the check only warns. Registration is shown but not enforced.

Releasing

TEAM_ID=ABCDE12345 NOTARY_PROFILE=sigantara scripts/release.sh

Archives with Hardened Runtime, signs with Developer ID, notarizes, staples and checks Gatekeeper. Needs your Developer ID certificate and a notarytool keychain profile. An auto-updater is not included: the server has no macOS update manifest yet (README §11).

Notes

  • Tests use fixtures, a stub server (URLProtocol) and a fake X-Plane on loopback only. Never point automated tests at the production API.
  • -demo launch argument (Debug): sample data, no network, starting flights disabled. -snapshot <file.png> renders the window for review.
  • Datarefs in XPlane.DataRef are verified against X-Plane 12.4.3 DataRefs.txt and a live sim, but not yet against Windows XPlaneSimulator.cs.
  • Nil optional telemetry fields are omitted from JSON rather than sent as null (fine for Laravel nullable rules).
  • docs/acars-macos/check_contract.py runs only inside the server monorepo (it reads the PHP routes and Models.cs).
  • Debug builds are ad-hoc signed; Release enables Hardened Runtime.
  • The DREF landing-light write (README §8) exists in the codec only (XPlane.setLandingLights) and is never sent: what triggers it in the Windows client (XPlaneSimulator.cs/MainForm.cs) isn't available here.
S
Description
No description provided
Readme
206 KiB
0 Stars 1 Watchers 0 Forks
Languages
Swift 99.1%
Shell 0.9%