Skip to content

๐Ÿ‡จ๐Ÿ‡ฟ cz-caa โ€‹

CountryCzech Republic
Registration prefixOK-
Data sourcehttps://lr.caa.gov.cz/api/avreg/filtered (list) + https://lr.caa.gov.cz/api/avreg/{id} (detail)
FormatJSON API, two-step (list endpoint, then one detail request per active record)
Run frequencyWeekly (Tuesday, 21:10 UTC)
Depends on Mictronics for ICAO hexNo โ€” the detail record's transponder field is the Mode S hex address directly.

How it works โ€‹

The list endpoint (.../avreg/filtered?start=0&length=10000) returns all records, which are filtered client-side to those with deletion_date == null (i.e. still active). Each active record's id is then used to fetch a full detail record from a per-aircraft endpoint, with a 0.25s delay between requests and retry-with-backoff (up to 3 attempts) on 403/429/5xx responses and connection errors. Records without a non-empty transponder value are skipped, since that field becomes the Redis key. The detail record's owners list is used in full (every display_name present, not just the first) to populate registrant.names; the detail record also carries a distinct operators field (e.g. an aeroclub that owns a glider operated by a separate flying school) but it is intentionally not read โ€” only owners is tracked for registrant identity. 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
id (list endpoint)โŒUsed only to build the per-record detail request URL; not stored
deletion_dateโŒUsed to filter to active (non-deleted) records only; value itself is not stored
transponderโœ…โ†’ icao_hex (skipped if null/empty)
registration_numberโœ…OK- prefix prepended โ†’ registration
categoryโœ…Decoded via a category map (e.g. AVREG_DATA.CATEGORIES.AIRPLANE โ†’ Airplane) โ†’ aircraft.type
type (detail endpoint)โŒFree-text type/model designation (e.g. SZD-45A) distinct from the coded category field; present in source, not read by this runner
manufacturerโœ…โ†’ aircraft.manufacturer
modelโœ…โ†’ aircraft.model
serial_numberโœ…โ†’ aircraft.serial_number
manufacture_yearโœ…Integer year (1900โ€“2100) โ†’ aircraft.manufactured_date (YYYY-01-01)
registration_dateโŒPresent in source; not read by this runner
mtowโŒPresent in source; not read by this runner
colorโŒPresent in source; not read by this runner
pledgeโŒPresent in source; not read by this runner
pledge_textโŒPresent in source; not read by this runner
sanctionsโŒPresent in source; not read by this runner
sanctions_textโŒPresent in source; not read by this runner
transfer_of_rightsโŒPresent in source; not read by this runner
transfer_of_rights_textโŒPresent in source; not read by this runner
engine_typeโœ…Decoded via an engine-type map; NO_ENGINE omitted entirely โ†’ aircraft.powerplant.type
engine_countโœ…โ†’ aircraft.powerplant.count
max_on_boardโœ…โ†’ aircraft.seats
owners[].display_nameโœ…All non-empty display names โ†’ registrant.names[]
owners[].legal_idโŒPresent in source; not read by this runner
operators[].display_nameโŒDistinct from owners on many records; present in source, intentionally not read
operators[].legal_idโŒPresent in source; not read by this runner

See specs/data-dictionary.yaml (cz-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 49D160 | python3 -m json.tool --sort-keys --no-ensure-ascii
json
{
    "aircraft": {
        "manufactured_date": "1974-01-01",
        "manufacturer": "REIMS AVIATION S.A.",
        "manufacturer_model": "CESSNA 172 Skyhawk",
        "model": "FR 172 J",
        "powerplant": {
            "count": 1,
            "type": "Piston"
        },
        "seats": 4,
        "serial_number": "0471",
        "type": "Airplane",
        "type_designator": "C172",
        "wake_turbulence_category": "Light"
    },
    "icao_hex": "49D160",
    "military": false,
    "registrant": {
        "names": [
            "Carnovia Aero s.r.o."
        ]
    },
    "registration": "OK-EKM",
    "source": "cz-caa"
}
bash
docker run --rm --network host redis:latest redis-cli EVAL "$(cat ./shared/lua/merge_aircraft.lua)" 0 49D166 | python3 -m json.tool --sort-keys --no-ensure-ascii
json
{
    "aircraft": {
        "manufactured_date": "1976-01-01",
        "manufacturer": "PZL MIELEC",
        "manufacturer_model": "ANTONOV An-2",
        "model": "An-2",
        "powerplant": {
            "count": 1,
            "type": "Piston"
        },
        "seats": 14,
        "serial_number": "1G16801",
        "type": "Airplane",
        "type_designator": "AN2",
        "wake_turbulence_category": "Light"
    },
    "icao_hex": "49D166",
    "military": false,
    "registrant": {
        "names": [
            "Aeroklub Novรฉ Mฤ›sto nad Metujรญ, z. s."
        ]
    },
    "registration": "OK-GIB",
    "source": "cz-caa"
}

Note: OK-GIB (an Antonov An-2) is used here in place of the more typical "big example" because Mictronics currently mislabels the widebody-adjacent OK-OJL registration as an A319, when it is actually a Zlin Z-37 ฤŒmelรกk โ€” this is a known upstream data-quality issue, not a bug in this runner.

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/cz-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_cz_caa_{name}/config for each of the three stats above.