Skip to content

Bahamas ๐Ÿ‡ง๐Ÿ‡ธ CAA Registry โ€‹

Namebs-caa-registry
CountryBahamas
Registration prefixC6-
Data sourcehttps://caabahamas.com/registers/
FormatPDF (date-stamped filename, discovered via index page)
Run frequencyWeekly (Friday, 05:10 UTC)
Depends on Mictronics for ICAO hexYes โ€” this runner does not publish ICAO hex addresses; registrations are resolved via RediSearch against Mictronics records (idx:aircraft:mictronics). Must run after the mictronics runner.

How it works โ€‹

The Bahamas CAA registers index page is scraped for a link matching Updated-THE-BAHAMAS-CIVIL-AIRCRAFT-REGISTER*.pdf (tried first as an absolute URL, then as a relative href), and that PDF is downloaded to a temp file. Unlike the other PDF-based runners in this project, this one relies on pdfplumber's built-in extract_table() rather than manual x-position grouping โ€” the Bahamas PDF is Excel-generated with clean table borders, so pdfplumber detects columns reliably. Because the header row repeats on every page, any row that matches the captured header exactly is skipped. Registrations are resolved to icao_hex in batches of 100 via RediSearch against the Mictronics index, then a type sanity check compares tokens from the combined make/model column against the existing Mictronics record, rejecting the match only when both sides have tokens and none overlap. The Bahamas register carries only owner name, registration, a single combined make/model string, and serial number โ€” no manufacturer, type designator, or powerplant fields are available at the source. Owner, make/model, and serial number are all whitespace-collapsed, since pdfplumber can represent a wrapped cell's text with an embedded newline rather than a space. 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
AIRCRAFT REGISTRATIONโœ…C6--prefix; used as the Mictronics lookup key
AIRCRAFT MANUFACTURER & DESIGNATIONโœ…โ†’ aircraft.model (combined make/model, not split); embedded newlines collapsed to a single space; also used for the type sanity check against Mictronics
AIRCRAFT SERIAL NUMBERโœ…โ†’ aircraft.serial_number; embedded newlines collapsed to a single space
REGISTERED OWNER OF AIRCRAFTโœ…โ†’ registrant.names[0]; embedded newlines collapsed to a single space

The CAA has renamed these headers before without notice. The parser now aborts with an error if it extracts data rows that lack the registration column, rather than silently importing zero records, so a future rename surfaces as a failed run instead of a clean-looking empty one.

See specs/data-dictionary.yaml (bs-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 0A80AD | python3 -m json.tool --sort-keys --no-ensure-ascii
json
{
    "aircraft": {
        "manufacturer": "PIPER",
        "manufacturer_model": "PIPER PA-23-250 Aztec",
        "model": "PA23-250",
        "serial_number": "27-7405407",
        "type_designator": "PA27"
    },
    "data_sources": [
        "mictronics",
        "bs-caa-registry"
    ],
    "icao_hex": "0A80AD",
    "military": false,
    "registrant": {
        "names": [
            "FYLDEN RUSSELL"
        ]
    },
    "registration": "C6-FJR"
}
bash
docker run --rm --network host redis:latest redis-cli EVAL "$(cat ./shared/lua/merge_aircraft.lua)" 0 0A80C2 | python3 -m json.tool --sort-keys --no-ensure-ascii
json
{
    "aircraft": {
        "manufacturer": "BOEING",
        "manufacturer_model": "BOEING 737-700",
        "model": "B737-752",
        "serial_number": "30038",
        "type_designator": "B737"
    },
    "data_sources": [
        "mictronics",
        "bs-caa-registry"
    ],
    "icao_hex": "0A80C2",
    "military": false,
    "registrant": {
        "names": [
            "BAHAMASAIR HOLDINGS LTD."
        ]
    },
    "registration": "C6-BFZ"
}

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