Skip to content

๐Ÿ‡ณ๐Ÿ‡ด no-caa โ€‹

CountryNorway
Registration prefixLN-
Data sourcehttps://data.caa.no/nlr/norgesluftfartoyregister.json
FormatJSON API (fixed URL)
Run frequencyWeekly (Wednesday, 06:10 UTC)
Depends on Mictronics for ICAO hexNo โ€” 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.

Columns โ€‹

Source columnImportedNotes
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 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):

bash
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
json
{
    "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",
        "wake_turbulence_category": "Light"
    },
    "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",
    "source": "no-caa"
}
bash
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
json
{
    "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",
        "wake_turbulence_category": "Medium"
    },
    "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",
    "source": "no-caa"
}

Configuration โ€‹

Reads settings.json (mounted at /app/settings.json):

ParameterRequiredDefaultNotes
redis.hostโœ…โ€”Redis connection host
redis.portโŒ6379
mqtt.hostโŒโ€”Omit the whole mqtt block to skip completion-stats publishing entirely
mqtt.portโŒ1883
mqtt.usernameโŒโ€”Optional MQTT auth; omit for an anonymous broker
mqtt.passwordโŒโ€”
redis_ttl_daysโŒ14TTL applied to each aircraft:registry:{icao_hex} key written by this runner

MQTT โ€‹

Published once, at the end of a run, to SkyFollower/runner/no-caa/statistic/{name} (all retained):

Topic suffixValueFormat
records_importede.g. 271Integer as string
last_run_ate.g. 2026-07-07T14:32:01.123456+00:00ISO 8601 UTC
last_run_statussuccess or failureString

Home Assistant autodiscovery configs are also published (retained) to homeassistant/sensor/SkyFollower_runner_no_caa_{name}/config for each of the three stats above.