← Terug naar blog
AI Toepassingen

Een persoonlijke vliegtuigmonitor bouwen met AI: van nieuwsgierigheid tot live melding

Tim Derdelinckx  •  18 juli 2026

Mijn dochter is enorme fan van Flightradar24: het traject van vliegtuigen volgen en indien mogelijk het vliegtuig live spotten in de lucht.
We gaan geregeld naar de spottersplaatsen in Zaventem en zijn altijd hoopvol om specifieke toestellen te kunnen zien: uiteraard een Beluga, een Airbus A380 of een CRJ1000. Niet noodzakelijk zeldzaam op wereldschaal, maar wel leuk genoeg om te willen weten wanneer ze in de buurt komen.
Dus kwam mijn dochter met de eenvoudige vraag: hoe kan ik weten wanneer mijn favoriete toestellen in de buurt zijn?
Dus antwoordde ik Barney-gewijs: challende accepted!
Een systeem bouwen dat onze favoriete toestellen volgt en mij een bericht stuurt wanneer er eentje boven België dreigt te passeren!

Wat begon als een idee voor een klein agentje, werd een echt project met een website, databank, monitorjob, kaartweergave en e-mailmeldingen. Ik bouwde de eerste versie samen met Codex. Niet als een magische knop die alles oplost, maar als een technische sparringpartner die mee nadenkt, code schrijft, documentatie bijhoudt en vooral helpt wanneer de echte wereld zich niet helemaal aan het plan houdt.

Wat ik wilde bouwen

De bedoeling is een persoonlijke monitor, geen professionele flight-trackingdienst. De applicatie moet een lijst van interessante toestellen en regio's beheren, geregeld vluchtdata ophalen en een detailpagina tonen wanneer er een match is. De kernvraag is niet alleen: “waar is dat vliegtuig nu?”, maar ook: “zal het vermoedelijk over België vliegen?”

  • Een configureerbare lijst met vliegtuigtypes en individuele toestellen
  • Regio's als echte geografische zones, met België als startpunt
  • Een job die elke 15 minuten vluchtdata controleert
  • Een bericht met link naar een detailpagina wanneer er iets interessants gebeurt
  • Een beheerpagina om regels en regio's aan te passen zonder in code te moeten werken
Een nuance die belangrijk bleek:
Een bestemming vertelt niet automatisch of een toestel boven België zal komen. Daarom werkt de applicatie met drie labels: confirmed voor een actuele positie in de regio, planned voor een route van de provider en estimated voor een berekende route. Dat onderscheid voorkomt dat een interessante schatting als zekerheid wordt verkocht.

De architectuur: twee machines, elk met een duidelijke taak

Ik had al twee always-on toestellen in huis: een Synology NAS en een Mac mini M4. In plaats van alles op één plaats te proppen, hebben we de taken verdeeld volgens waar ze het best passen.

  • Synology NAS: Apache, PHP 8.4, MySQL, de beheerwebsite en de publieke detailpagina's
  • Mac mini: een Python-monitorjob die automatisch draait via launchd
  • OpenSky: de eerste databron voor live ADS-B-posities
  • SMTP: de eerste werkende notificatievorm, met WhatsApp als volgende stap via de officiële API

De Mac haalt de configuratie beveiligd op bij de Synology, raadpleegt de data-provider en schrijft gevonden vluchten en matches terug via een aparte API. De website hoeft dus zelf geen externe API-sleutels te kennen. Dat is niet alleen netter, maar ook een pak veiliger.

België is geen tekstveld

“België” klinkt als een simpel veld in een formulier, maar voor een computer is het pas bruikbaar als een vorm op een kaart. Daarom wordt een regio opgeslagen als GeoJSON-polygoon: een reeks lengte- en breedtegraden die samen de landsgrens vormen. Daardoor kan de monitor een berekende route effectief snijden met de regio, in plaats van alleen te gokken op basis van een centrum-punt of een rechthoek.

Voor een route zonder route-informatie van de provider gebruikt de monitor een gesamplede grootcirkelroute. Dat is realistischer dan een rechte lijn op een platte kaart. Voor een persoonlijke toepassing is dat een mooie middenweg tussen eenvoud en eerlijkheid over de onzekerheid.

Van briefing naar werkende applicatie

De eerste oplevering was bewust een volledig, maar klein MVP. De serverkant kreeg een login, CSRF-bescherming, versiegeschiedenis voor de JSON-configuratie, een beveiligde bearer-token-API en een detailpagina met een niet-voorspelbare link. De MySQL-database bewaart vluchten, matches, notificaties en de status van elke monitorrun.

Op de Mac kwam een Python-app met een lockfile tegen overlappende uitvoeringen, logging, e-maildeduplicatie en tests voor de geografische berekeningen. Er zit ook een deterministische demo-provider in. Daarmee konden BelugaXL-, CRJ1000- en A380-scenario's van begin tot einde getest worden zonder meteen van een commerciële datafeed of een toevallig vliegtuig in de lucht afhankelijk te zijn.

Waarom een demo-provider zo waardevol is:
Een live systeem is lastig te testen als het interessante toestel net niet vliegt. Met vaste demo-vluchten kun je de volledige keten herhalen: vertrek detecteren, route door België bepalen, match opslaan en een melding genereren. Pas wanneer dat betrouwbaar werkt, heeft het zin om live data toe te voegen.

De installatie was het echte project

Code schrijven is één ding. Ze correct laten draaien op een NAS, over VLAN's heen en met een Mac die de job uitvoert, is waar een project echt wordt. De installatiehandleidingen waren daarom even belangrijk als de applicatie zelf.

Op de Synology liepen we tegen typische DSM-eigenheden aan. Een klassieke chown werkte niet zoals verwacht omdat gedeelde mappen door DSM-ACL's worden beheerd. De juiste oplossing was de http-groep via File Station de nodige lees- en schrijfrechten geven. Dat is zo'n detail dat je niet in een mooi architectuurdiagram ziet, maar dat wel bepaalt of een website functioneert.

Daarna bleek de PHP-runtime van de SSH-shell niet dezelfde te zijn als die van Web Station. pdo_mysql was correct geactiveerd in PHP-FPM, terwijl de CLI geen database-driver vond. De database-migratie rechtstreeks uitvoeren in MariaDB en een tijdelijke diagnosepagina toevoegen maakte de echte fout zichtbaar: niet de code, maar database-toegang vanuit PHP-FPM.

Debuggen zonder gokwerk:
Een goede diagnosepagina toonde PHP-versie, actieve PDO-drivers, leesbaarheid van de configuratie, databaseverbinding en aanwezige tabellen, zonder geheimen prijs te geven. Daardoor veranderde “interne serverfout” in een concrete, oplosbare taak.

Ook de Mac had zijn eigen handleiding

De monitor draait niet via een traditioneel cronjobje, maar via launchd. Dat sluit beter aan bij macOS en houdt logs, herstarts en planning op één plaats. De job draait onder de gewone Mac-gebruiker, niet onder een vaag “admin”-account. Dat klinkt klein, maar bepaalt waar de virtuele Python-omgeving, logs en rechten precies terechtkomen.

Ook daar waren er leermomenten. De aanwezige Python-versie was 3.11 terwijl het project Python 3.12 verwachtte. Een test onthulde vervolgens een echte geometriebug: bij een route door België werd soms de verkeerde landsgrens als eerste kruispunt gekozen. Dat is precies waarom tests geen luxe zijn. Na de correctie testte de code expliciet zowel west-naar-oost als oost-naar-west.

Een melding versturen is meer dan SMTP invullen

De eerste notificaties gaan via e-mail. Dat was een bewuste keuze: gemakkelijk te testen, betrouwbaar en voldoende om de volledige flow te bewijzen. De SMTP-server draaide op de Synology in een ander VLAN en enkel poort 25 en 465 waren beschikbaar. Poort 465 gebruikt impliciete TLS, niet STARTTLS. De notifier moest dus expliciet SMTPS ondersteunen.

E-mailbericht

Daarna volgde nog een vertrouwde klassieker: een certificaat dat niet geldig was voor het gebruikte IP-adres. De les is eenvoudig: gebruik voor versleutelde interne diensten de hostnaam die op het certificaat staat, niet zomaar een IP-adres. Uiteindelijk vertrok de testmail, en daarmee was de volledige keten bewezen.

Wat vandaag live werkt, en wat de volgende stap is

De eerste versie draait: de website, databank, beveiligde API, launchd-monitor, demo's, logging en e-mailnotificaties werken samen. De OpenSky-integratie gebruikt OAuth2 en blijft ruim binnen het dagelijkse kredietbudget bij een controle om de 15 minuten.

De link in de e-mail

Er zit wel een belangrijke grens in de huidige live databron. OpenSky live state vectors zijn uitstekend voor de positie van een specifiek toestel, geïdentificeerd met zijn ICAO24-hexcode. Ze leveren echter niet consequent het vliegtuigtype, vertrek, bestemming of geplande route. De eerste live versie kan dus individuele toestellen betrouwbaar bevestigen wanneer ze boven België zijn. Voor automatisch “alle A380's” of een voorspelling vóór de grens, is een extra vliegtuigdatabase of een rijkere commerciële provider nodig.

Configuratie van de flight monitor
De interessante volgende iteratie:
Vliegtuigtype-verrijking koppelen aan ICAO24-codes en een provider toevoegen die vertrek, bestemming en route levert. Dan kan de applicatie precies doen waarvoor het idee ooit begon: niet alleen vertellen dat een toestel er al is, maar vooraf waarschuwen dat het eraan komt.

Samenwerken met Codex

Het meest interessante deel was niet de code op zich, maar de manier van werken. Codex (ik koos voor GPT-5.6 Sol) hielp bij het vertalen van een los idee naar een technische briefing, bouwde een eerste versie, schreef installatiehandleidingen en paste die aan zodra de echte omgeving iets anders deed dan verwacht. De conversatie ging voortdurend heen en weer tussen architectuur en heel concrete vragen: welke PHP-runtime draait hier? Welke gebruiker hoort in deze plist? Waarom wordt dit certificaat geweigerd?

Configuratie van de flight monitor

Dat maakt AI voor mij vooral nuttig als versneller van kleine, persoonlijke projecten. Je hoeft niet eerst een volledig team of een zware cloudomgeving te hebben om iets te bouwen dat echt op jouw infrastructuur en interesses aansluit. Je moet wel bereid zijn om mee te denken, te testen en af en toe te aanvaarden dat “interne serverfout” het begin is van het interessante werk. Ook enige ervaring en kennis van het opzetten blijken wel een absolute meerwaarde om dergelijk project tot een goed eind te krijgen.

Conclusie

Een persoonlijke vliegtuigmonitor is een fijn voorbeeld van wat er mogelijk wordt wanneer je een concrete interesse koppelt aan bestaande infrastructuur en AI als co-developer. Het resultaat is geen generieke app, maar een klein systeem dat precies doet wat ik wil: de lucht boven België een beetje interessanter maken. En het mooiste is dat de eerste live melding niet het einde van het project is, maar het begin van de volgende verbetering.