Skip to content

New Zealand ๐Ÿ‡ณ๐Ÿ‡ฟ CAA Registry โ€‹

Namenz-caa-registry
CountryNew Zealand
Registration prefixZK-
Data sourcehttps://www.aviation.govt.nz/assets/aircraft/aircraft-register/Aircraft-Register-for-website.csv
FormatCSV (fixed URL)
Run frequencyWeekly (Wednesday, 05:10 UTC)
Depends on Mictronics for ICAO hexNo โ€” the CSV publishes its own Mode S Code HEX column, so icao_hex is read directly from the source data.

How it works โ€‹

The CSV is downloaded whole from a fixed URL and decoded as utf-8-sig (the file carries a BOM), then parsed with csv.DictReader. The genuinely tricky part is Owner Address: it's a single free-text field shaped like "Street 1[, Street 2, ...], City PostalCode, Country". _parse_address splits on ", ", treats the last segment as the country and the second-to-last as a combined "City PostalCode" pair (matched with a regex), and falls back to treating everything but the last segment as street lines when the city/postal pattern doesn't match or the candidate city looks like a PO box. 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
Mode S Code HEXโœ…ICAO hex; record is dropped entirely if blank
Registration Markโœ…โ†’ registration
Model Categoryโœ…โ†’ aircraft.type, decoded via lookup table (e.g. Aeroplane (Aircraft) โ†’ Airplane)
Manufacturerโœ…โ†’ aircraft.manufacturer
Modelโœ…โ†’ aircraft.model
Serial No.โœ…โ†’ aircraft.serial_number
Owner Nameโœ…โ†’ registrant.names[0]
Owner Addressโœ…Free-text parsed into registrant.street[] / city / postal_code / country
Registered onโŒPresent in source; not read by this runner
MCTOW (Kg)โŒPresent in source; not read by this runner
Mode S Code BinaryโŒPresent in source; not read by this runner
Flight manual no.โŒPresent in source; not read by this runner

See specs/data-dictionary.yaml (nz-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):

bash
docker run --rm --network host redis:latest redis-cli EVAL "$(cat ./shared/lua/merge_aircraft.lua)" 0 C804C7 | python3 -m json.tool --sort-keys --no-ensure-ascii
json
{
    "aircraft": {
        "manufacturer": "Cessna Aircraft Company",
        "manufacturer_model": "CESSNA 152",
        "model": "A152",
        "serial_number": "A1520919",
        "type": "Airplane",
        "type_designator": "C152"
    },
    "data_sources": [
        "mictronics",
        "nz-caa-registry"
    ],
    "icao_hex": "C804C7",
    "military": false,
    "registrant": {
        "city": "Wellington",
        "country": "NZ",
        "names": [
            "Roc On Aviation Limited"
        ],
        "postal_code": "6022",
        "street": [
            "15 Bowes Crescent",
            "Strathmore Park"
        ]
    },
    "registration": "ZK-NPH"
}
bash
docker run --rm --network host redis:latest redis-cli EVAL "$(cat ./shared/lua/merge_aircraft.lua)" 0 C81E2C | python3 -m json.tool --sort-keys --no-ensure-ascii
json
{
    "aircraft": {
        "manufacturer": "Airbus",
        "manufacturer_model": "AIRBUS A-320",
        "model": "A320-232",
        "serial_number": "4926",
        "type": "Airplane",
        "type_designator": "A320"
    },
    "data_sources": [
        "mictronics",
        "nz-caa-registry"
    ],
    "icao_hex": "C81E2C",
    "military": false,
    "registrant": {
        "city": "Auckland",
        "country": "NZ",
        "names": [
            "Air New Zealand Limited"
        ],
        "postal_code": "1142",
        "street": [
            "C/- Internal Address AKL 43/G",
            "Private Bag 92007",
            "Victoria Street West"
        ]
    },
    "registration": "ZK-OJS"
}

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/nz-caa-registry/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_nz_caa_registry_{name}/config for each of the three stats above.