Skip to content

Suriname ๐Ÿ‡ธ๐Ÿ‡ท CASAS Registry โ€‹

Namesr-casas-registry
CountrySuriname
Registration prefixPZ-
Data sourcehttps://www.casas.sr/registry/
FormatXlsx (discovered via index page)
Run frequencyWeekly (pick a day/time โ€” see docker-compose.core.yaml)
Depends on Mictronics for ICAO hexYes โ€” this runner does not publish ICAO hex addresses; PZ- registrations are resolved via RediSearch against Mictronics records (idx:aircraft:mictronics). Must run after the mictronics runner.

How it works โ€‹

The CASAS registry page links two xlsx files โ€” the Civil Aircraft Register and a separate UAS/drone registry โ€” so the index page is scraped for a link matching REGISTER-{MM}-{YYYY}.xlsx specifically (the UAS file is named CASAS-UAS-REGISTRY-{Mon}-{YYYY}.xlsx and doesn't match). The xlsx has a clean named header row, so columns are read by name via dict(zip(headers, row)) rather than by fixed position. The full registration mark isn't a single column โ€” it's NATIONALITY MARK OR COMMON MARK (always PZ in the source, but read dynamically rather than hardcoded) concatenated with REGISTRATION MARK (e.g. PZ + UBD โ†’ PZ-UBD).

The source has both a MAKE and a MANUFACTURER column that differ on about half of all rows (e.g. MAKE=GRUMMAN, MANUFACTURER=SCHWEIZER for Grumman Ag-Cat airframes later built under license by Schweizer) โ€” shared/models.py's AircraftRecord has only one manufacturer field, so MAKE (the type's brand) is used and MANUFACTURER is dropped. The source also has a separate OPERATOR (*) column alongside OWNER_NAME โ€” matching the established convention across every other runner in this repo with both an owner and an operator column (e.g. lu-dac-registry, sk-nsat-registry), only owner becomes registrant.names; operator is present in source but intentionally not read, since no runner in this codebase writes AircraftRecord's top-level operator field. MODEL and SERIES are concatenated when both are present (e.g. G164 + B โ†’ G164B); about 14% of rows have no SERIES value. Every written record explicitly sets military: false โ€” this register is exclusively civil.

Columns โ€‹

Source columnImportedNotes
#โŒRow sequence number
MAKEโœ…โ†’ aircraft.manufacturer
MODELโœ…โ†’ aircraft.model (trailing * stripped โ€” one row in the source has G164*, apparently a stray marker); SERIES appended when present
SERIESโœ…Appended to aircraft.model; absent on ~14% of rows
MANUFACTURERโŒDiffers from MAKE on ~half of rows (licensed-builder detail); MAKE wins since there's only one manufacturer field
SERIAL_NUMBERโœ…โ†’ aircraft.serial_number; source has mixed string/numeric cell types, coerced to string
NATIONALITY MARK OR COMMON MARKโœ…Always PZ in the source; used as the registration prefix
REGISTRATION MARKโœ…Registration suffix; concatenated with the nationality mark as the lookup key
OWNER_NAMEโœ…โ†’ registrant.names
OPERATOR (*)โŒPresent in source but not read โ€” see "How it works" above

See specs/data-dictionary.yaml (sr-casas-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 3A1234 | python3 -m json.tool --sort-keys --no-ensure-ascii
json
{
    "aircraft": {
        "manufacturer": "GRUMMAN",
        "manufacturer_model": "Grumman G-164 Ag Cat",
        "model": "G164B",
        "serial_number": "185B",
        "type_designator": "AGCT"
    },
    "data_sources": [
        "mictronics",
        "sr-casas-registry"
    ],
    "icao_hex": "3A1234",
    "military": false,
    "registrant": {
        "names": [
            "SURINAM SKY FARMERS"
        ]
    },
    "registration": "PZ-UBD"
}

(type_designator and manufacturer_model come from a Mictronics record on the same hex; manufacturer, model, serial_number, and registrant.names above are this runner's contribution โ€” note manufacturer (GRUMMAN, this runner's MAKE value) wins over Mictronics' own manufacturer field on conflict, per merge_aircraft.lua's mictronics โ†’ registry โ†’ livery priority order.)

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/sr-casas-registry/statistic/{name} (all retained):

Topic suffixValueFormat
records_importede.g. 100Integer as string
last_run_ate.g. 2026-08-08T21:52:58.718000+00:00ISO 8601 UTC
last_run_statusSuccess or FailureString

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