Skip to content

Togo ๐Ÿ‡น๐Ÿ‡ฌ ANAC Registry โ€‹

Nametg-anac-registry
CountryTogo
Registration prefix5V-
Data sourcehttp://www.anac-togo.tg/espace-professionnel/aeronefs/consultation-du-registre-dimmatriculation/
FormatHTML table (single request, no file to download)
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; 5V- registrations are resolved via RediSearch against Mictronics records (idx:aircraft:mictronics). Must run after the mictronics runner.

How it works โ€‹

The register is embedded as a single HTML <table> on the page, so there's no discovery step โ€” one request, parsed with BeautifulSoup. Despite its header, the type column holds model designations (e.g. DC8 62, PA 31T), not the aircraft.type category vocabulary (Airplane/Rotorcraft/etc.) โ€” the source's own column naming is misleading, so this column maps to aircraft.model.

The table's Radiation column (OUI/NON, "deregistered?") is a real, majority filter, not an edge case: at check time only 13 of 46 rows (28%) were Radiation = NON (active); the other 32 (70%) were OUI (deregistered) and are dropped. Only NON rows are written. One row in the live data has (Radiรฉ) appended to every cell including the registration mark itself (a data-entry artifact, not the normal OUI/NON encoding) โ€” this gets rejected by the registration-mark regex before the Radiation check even runs, so it's excluded regardless. Registration marks are validated against ^5V-[A-Z0-9]{2,6}$, verified against every real row in the live table (both active and deregistered) before choosing that width. Every written record explicitly sets military: false โ€” this register is exclusively civil.

Columns โ€‹

Source columnImportedNotes
Nยฐ OrdreโŒSequence number
typeโœ…โ†’ aircraft.model โ€” despite the header name, holds model designations, not the aircraft.type category
Immatriculationโœ…5V--prefix; used as the Mictronics lookup key
Constructeurโœ…โ†’ aircraft.manufacturer
Nยฐ de serieโœ…โ†’ aircraft.serial_number
Radiationfilter onlyOUI = deregistered (majority of rows), NON = active (kept)
Nom propriรฉtaireโœ…โ†’ registrant.names; blank on many rows
Adresse propriรฉtaireโœ…โ†’ registrant.street, comma-split; blank on many rows; a few rows have a phone number here instead of an address (source data quirk, stored as-is)

See specs/data-dictionary.yaml (tg-anac-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 500A1B | python3 -m json.tool --sort-keys --no-ensure-ascii
json
{
    "aircraft": {
        "manufacturer": "PIPER AIRCRAFT",
        "manufacturer_model": "Piper PA-31T Cheyenne",
        "model": "PA 31T",
        "serial_number": "7820013",
        "type_designator": "PA31"
    },
    "data_sources": [
        "mictronics",
        "tg-anac-registry"
    ],
    "icao_hex": "500A1B",
    "military": false,
    "registrant": {
        "names": [
            "Mr SITTERLIN"
        ],
        "street": [
            "BP 10019 Lomรฉ TOGO"
        ]
    },
    "registration": "5V-TPT"
}

(type_designator and manufacturer_model come from a Mictronics record on the same hex; manufacturer, model, serial_number, and registrant above are this runner's contribution โ€” note manufacturer (PIPER AIRCRAFT, this runner's 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/tg-anac-registry/statistic/{name} (all retained):

Topic suffixValueFormat
records_importede.g. 13Integer as string
last_run_ate.g. 2026-08-08T22:21:47.388000+00:00ISO 8601 UTC
last_run_statusSuccess or FailureString

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