Norway ๐ณ๐ด CAA Registry โ
| Name | no-caa-registry |
| Country | Norway |
| Registration prefix | LN- |
| Data source | https://data.caa.no/nlr/norgesluftfartoyregister.json |
| Format | JSON API (fixed URL) |
| Run frequency | Weekly (Wednesday, 06:10 UTC) |
| Depends on Mictronics for ICAO hex | No โ the register publishes its own ICAO 24-bit address (Heksadesimal) for every aircraft, so icao_hex is read directly from the source data. |
How it works โ
The Norway CAA register is downloaded whole from a fixed URL as a single JSON payload ({headers, data: [...]}); no index page or scraping is involved. Each record's ICAO hex is pulled from the Heksadesimal field inside the ICAO 24-bits adresse array. Aircraft category (Kategori) and owner country (Land) are decoded via lookup tables โ Norwegian names are used for Norway/Sweden/Denmark and English names for everything else โ with unmapped values passed through as-is rather than dropped. Owners (Eier(e)) is an array that may hold multiple entries; the one flagged Eier/Kontakt supplies the registrant's address, while names are collected from every owner entry (contact first, then any others, de-duplicated). Every written record explicitly sets military: false โ this register is exclusively civil, and the explicit value ensures a stale military: true flag (from Mictronics or a prior record on a reused hex) is corrected on re-registration.
Deduced ICAO type designator โ
This register never publishes an ICAO type designator โ only a raw manufacturer/model string (Produsent/Type). This runner deduces one for hexes Mictronics has no entry for by consensus: hexes Mictronics does already label become training data, grouped by normalized (manufacturer, model); a group's majority Mictronics designator is applied to that group's other, unlabelled hexes when the group has at least 3 labelled examples and at least 90% agreement, otherwise the gap is left as-is. A deduced designator also gets its matching description_code, resolved from the aircraft:type:{designator} reference Redis already carries. See shared/type_designator_consensus.py and issue #1888 for the method and its measured precision/coverage.
Columns โ
| Source column | Imported | Notes |
|---|---|---|
ICAO 24-bits adresse (Heksadesimal) | โ | ICAO hex; record is dropped entirely if missing |
ICAO 24-bits adresse (Desimal) | โ | Present in source; not read by this runner |
ICAO 24-bits adresse (Binรฆr) | โ | Present in source; not read by this runner |
ICAO 24-bits adresse (Oktal) | โ | Present in source; not read by this runner |
Registreringsmerke | โ | โ registration |
Kategori | โ | โ aircraft.type, decoded (Fly/Helikopter/Seilfly/Ballong โ English) |
Produsent | โ | โ aircraft.manufacturer |
Type | โ | โ aircraft.model |
Serienummer | โ | โ aircraft.serial_number |
Byggeรฅr | โ | โ aircraft.manufactured_date (4-digit year converted to ISO 8601 UTC) |
Registreringsdato | โ | Present in source; not read by this runner |
Luftdyktighetskategori | โ | Present in source; not read by this runner |
Startmasse MTOM | โ | Present in source; not read by this runner |
Eier/Kontakt (top-level string) | โ | Present in source; not read by this runner โ distinct from the Eier(e) array's Eier/Kontakt-flagged entry, which is used |
Organisasjonsnummer eier/kontakt | โ | Present in source; not read by this runner |
Operatรธr | โ | Present in source; not read by this runner |
Organisasjonsnummer operatรธr | โ | Present in source; not read by this runner |
Eier(e) โ Eier type | โ | Used to select the Eier/Kontakt entry for address fields |
Eier(e) โ Eier siden | โ | Present in source; not read by this runner |
Eier(e) โ Navn | โ | โ registrant.names[] (contact first, then other owners, de-duplicated) |
Eier(e) โ Gateadresse | โ | โ registrant.street[] |
Eier(e) โ Poststed | โ | โ registrant.city |
Eier(e) โ Postnummer | โ | โ registrant.postal_code |
Eier(e) โ Land | โ | โ registrant.country, decoded to ISO 3166-1 alpha-2 where known |
Eier(e) โ Organisasjonsnummer | โ | Present in source; not read by this runner |
See specs/data-dictionary.yaml (no-caa-registry entry) for full column semantics and cross-source schema notes.
Example Output โ
Read back the merged record for a given ICAO hex (combines this runner's data with Mictronics and any other sources that have written to the same key):
docker run --rm --network host redis:latest redis-cli EVAL "$(cat ./shared/lua/merge_aircraft.lua)" 0 478E11 | python3 -m json.tool --sort-keys --no-ensure-ascii{
"aircraft": {
"manufactured_date": "2019-01-01T00:00:00Z",
"manufacturer": "Textron Aviation Inc.",
"manufacturer_model": "CESSNA 172 Skyhawk",
"model": "172S",
"serial_number": "172S12244",
"type": "Airplane",
"type_designator": "C172"
},
"data_sources": [
"mictronics",
"no-caa-registry"
],
"icao_hex": "478E11",
"military": false,
"registrant": {
"city": "ARENDAL",
"country": "NO",
"names": [
"OSM AVIATION AIRTECH AS"
],
"postal_code": "4836",
"street": [
"Peder Thomassons gate 12"
]
},
"registration": "LN-AZE"
}docker run --rm --network host redis:latest redis-cli EVAL "$(cat ./shared/lua/merge_aircraft.lua)" 0 4791AC | python3 -m json.tool --sort-keys --no-ensure-ascii{
"aircraft": {
"manufactured_date": "2011-01-01T00:00:00Z",
"manufacturer": "The Boeing Company",
"manufacturer_model": "BOEING 737-800",
"model": "737-86N",
"serial_number": "39403",
"type": "Airplane",
"type_designator": "B738"
},
"data_sources": [
"mictronics",
"no-caa-registry"
],
"icao_hex": "4791AC",
"military": false,
"registrant": {
"city": "Co. Clare",
"country": "IE",
"names": [
"Celestial Ex-Im Trading 5 Limited"
],
"postal_code": "V14 AN29",
"street": [
"Aviation House, Shannon"
]
},
"registration": "LN-NIQ"
}Configuration โ
See Data Runners for the full list of environment variables every runner reads. This runner writes aircraft:registry:{icao_hex} with a fixed 14-day TTL (ENRICHMENT_TTL_SECONDS in shared/timing.py).
MQTT โ
Published once, at the end of a run, to SkyFollower/runner/no-caa-registry/statistic/{name} (all retained):
| Topic suffix | Value | Format |
|---|---|---|
records_imported | e.g. 271 | Integer as string |
last_run_at | e.g. 2026-07-07T14:32:01.123456+00:00 | ISO 8601 UTC |
last_run_status | Success or Failure | String |
Home Assistant autodiscovery configs are also published (retained) to homeassistant/sensor/SkyFollower_runner_no_caa_registry_{name}/config for each of the three stats above.