Canada ๐จ๐ฆ Transport Canada Registry โ
| Name | ca-transport-canada-registry |
| Country | Canada |
| Registration prefix | C- |
| Data source | https://wwwapps.tc.gc.ca/Saf-Sec-Sur/2/CCARCS-RIACC/download/ccarcsdb.zip |
| Format | ZIP (fixed URL) containing two CSV files, carscurr.txt (aircraft) and carsownr.txt (owners) |
| Run frequency | Weekly (Sunday, 05:10 UTC) |
| Depends on Mictronics for ICAO hex | No โ the CCARCS aircraft file publishes the Mode S transponder address directly as a 24-bit binary string, which this runner decodes to hex itself. |
How it works โ
The full CCARCS database ZIP is downloaded from a fixed URL and both member files are extracted in memory. carscurr.txt (aircraft) and carsownr.txt (owners) are ISO-8859-1, comma-delimited, and end with a blank row followed by a record-count row โ parsing stops at the first empty row to avoid ingesting that trailer. Rows are staged into a local SQLite database (indexed by registration) rather than being joined in Python, since owner records must be matched back to aircraft records by registration mark. Only aircraft rows with an empty ineffective_date (i.e. still on the register) are written to Redis, and only the first Active-status owner per registration is used. The Mode S column is a 24-bit binary string (e.g. "110000000000000000010000") converted to 6-character hex via int(value, 2) formatted as 06X. 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.
Deduced ICAO type designator โ
CCARCS never publishes an ICAO type designator โ only a raw manufacturer/model string. This runner deduces one for hexes Mictronics has no entry for by consensus: hexes Mictronics does already label become training data, grouped by normalized (manufacturer, model); a group's majority Mictronics designator is applied to that group's other, unlabelled hexes when the group has at least 3 labelled examples and at least 90% agreement, otherwise the gap is left as-is. A deduced designator also gets its matching description_code, resolved from the aircraft:type:{designator} reference Redis already carries. See shared/type_designator_consensus.py and issue #1888 for the method and its measured precision/coverage.
Columns โ
Both files are drawn from the same CCARCS ZIP and joined on the aircraft registration mark (carscurr.txt MARK/TRIMMED_MARK โ carsownr.txt MARK_LINK). Column names and order below match the archive's own carslayout.txt data dictionary, verified against the real downloaded files: 47 columns per row in carscurr.txt, 20 columns per row in carsownr.txt.
carscurr.txt (aircraft) โ
| Source column | Imported | Notes |
|---|---|---|
| MARK / TRIMMED_MARK | โ | C- prefix prepended; TRIMMED_MARK (col 46) preferred, falls back to stripped MARK (col 0) โ registration; also the join key to carsownr.txt MARK_LINK |
| REGISTRATION_SUB_TYPE_E | โ | Present in source; not read by this runner |
| REGISTRATION_SUB_TYPE_F | โ | Present in source; not read by this runner |
| COMMON_NAME | โ | Present in source; not read by this runner |
| MODEL_NAME | โ | โ aircraft.model |
| MANUFACTURERS_SERIAL_NUMBER | โ | โ aircraft.serial_number |
| MANUFACTURER_SERIAL_COMPRESSED | โ | Present in source; not read by this runner |
| ID_PLATE_MANUFACTURERS_NAME | โ | โ aircraft.manufacturer |
| BASIS_FOR_REGISTRATION | โ | Present in source; not read by this runner |
| BASIS_FOR_REGISTRATION_F | โ | Present in source; not read by this runner |
| AIRCRAFT_CATEGORY_E | โ | Decoded (e.g. Aeroplane โ Airplane) โ aircraft.type |
| AIRCRAFT_CATEGORY_F | โ | Present in source; not read by this runner |
| DATE_OF_IMPORT | โ | Present in source; not read by this runner |
| ENGINE_MANUF_E | โ | โ aircraft.powerplant.manufacturer |
| POWERGLIDER_FLAG | โ | Present in source; not read by this runner |
| ENGINE_CATEGORY_E | โ | Decoded (e.g. Turbo Fan โ Turbo-fan) โ aircraft.powerplant.type |
| ENGINE_CATEGORY_F | โ | Present in source; not read by this runner |
| NUMBER_OF_ENGINES | โ | โ aircraft.powerplant.count |
| NUMBER_OF_SEATS | โ | โ aircraft.seats |
| AIR_WEIGHT_KILOS | โ | Present in source; not read by this runner |
| SALE_REPORTED | โ | Present in source; not read by this runner |
| ISSUE_DATE | โ | Present in source; not read by this runner |
| EFFECTIVE_DATE | โ | Present in source; not read by this runner |
| INEFFECTIVE_DATE | โ | Used to filter to currently-registered aircraft only (ineffective_date == ''); value itself is not stored |
| REGISTERED_PURPOSE_E | โ | Present in source; not read by this runner |
| REGISTERED_PURPOSE_F | โ | Present in source; not read by this runner |
| FLIGHT_AUTHORITY_E | โ | Present in source; not read by this runner |
| FLIGHT_AUTHORITY_F | โ | Present in source; not read by this runner |
| MANUFACTURE_OR_ASSEMBLY | โ | Present in source; not read by this runner |
| COUNTRY_MANUFACTURE_ASS_E | โ | Present in source; not read by this runner |
| COUNTRY_MANUFACTURE_ASS_F | โ | Present in source; not read by this runner |
| DATE_MANUFACTURE_ASSEMBLY | โ | YYYY/MM/DD โ ISO 8601 UTC โ aircraft.manufactured_date |
| BASE_OF_OPERATIONS_CTRY_E | โ | Present in source; not read by this runner |
| BASE_OF_OPERATIONS_CTRY_F | โ | Present in source; not read by this runner |
| BASE_PROVINCE_OR_STATE_E | โ | Present in source; not read by this runner |
| BASE_PROVINCE_OR_STATE_F | โ | Present in source; not read by this runner |
| CITY_AIRPORT | โ | Present in source; not read by this runner |
| TYPE_CERTIFICATE_NUMBER | โ | Present in source; not read by this runner |
| REGISTRATION_AUTH_STATUS_E | โ | Present in source; not read by this runner |
| REGISTRATION_AUTH_STATUS_F | โ | Present in source; not read by this runner |
| MULTIPLE_OWNER_FLAG | โ | Present in source; not read by this runner |
| MODIFIED_DATE | โ | Present in source; not read by this runner |
| MODE_S_TRANSPONDER_BINARY | โ | 24-bit binary string decoded to 6-char hex โ icao_hex |
| PHYSICAL_FILE_REGION_E | โ | Present in source; not read by this runner |
| PHYSICAL_FILE_REGION_F | โ | Present in source; not read by this runner |
| EX_MILITARY_MARK | โ | Present in source; not read by this runner |
carsownr.txt (owners) โ
| Source column | Imported | Notes |
|---|---|---|
| MARK_LINK | โ | Join key back to the aircraft record's registration |
| FULL_NAME | โ | โ registrant.names[0] |
| TRADE_NAME | โ | โ registrant.names[1] |
| STREET_NAME | โ | โ registrant.street[0] |
| STREET_NAME2 | โ | โ registrant.street[1] |
| CITY | โ | โ registrant.city |
| PROVINCE_OR_STATE_E | โ | โ registrant.administrative_area |
| PROVINCE_OR_STATE_F | โ | Present in source; not read by this runner |
| POSTAL_CODE | โ | โ registrant.postal_code |
| COUNTRY_E | โ | Full English country name decoded to ISO 3166-1 alpha-2 (defaults to CA if unrecognized) โ registrant.country |
| COUNTRY_F | โ | Present in source; not read by this runner |
| TYPE_OF_OWNER_E | โ | โ registrant.type |
| TYPE_OF_OWNER_F | โ | Present in source; not read by this runner |
| ACTIVE_FLAG | โ | Used to select the current owner row (status == 'Active', first match only); value itself is not stored |
| CARE_OF | โ | Present in source; not read by this runner |
| REGION_E | โ | Present in source; not read by this runner |
| REGION_F | โ | Present in source; not read by this runner |
| OWNER_NAME_OLD_FORMAT | โ | Present in source; not read by this runner |
| MAIL_RECIPIENT | โ | Present in source; not read by this runner |
| TRIMMED_MARK | โ | Present in source; not read by this runner (distinct from carscurr.txt's own TRIMMED_MARK column) |
See specs/data-dictionary.yaml (ca-tc 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):
docker run --rm --network host redis:latest redis-cli EVAL "$(cat ./shared/lua/merge_aircraft.lua)" 0 C00010 | python3 -m json.tool --sort-keys --no-ensure-ascii{
"aircraft": {
"manufactured_date": "1966-01-01T00:00:00Z",
"manufacturer": "Piper Aircraft Corporation",
"manufacturer_model": "PIPER PA-32",
"model": "PA-32-260",
"powerplant": {
"count": 1,
"type": "Piston"
},
"serial_number": "32-528",
"type": "Airplane",
"type_designator": "PA32"
},
"data_sources": [
"mictronics",
"ca-transport-canada-registry"
],
"icao_hex": "C00010",
"military": false,
"registrant": {
"administrative_area": "Oklahoma",
"city": "Stillwater",
"country": "CA",
"names": [
"Roger D S Reetz"
],
"postal_code": "74074",
"street": [
"2701 S Mar Vista Street"
],
"type": "Individual"
},
"registration": "C-FAAP"
}docker run --rm --network host redis:latest redis-cli EVAL "$(cat ./shared/lua/merge_aircraft.lua)" 0 C038AA | python3 -m json.tool --sort-keys --no-ensure-ascii{
"aircraft": {
"manufactured_date": "2018-01-01T00:00:00Z",
"manufacturer": "THE BOEING COMPANY",
"manufacturer_model": "BOEING 787-9 Dreamliner",
"model": "787-9",
"powerplant": {
"count": 2,
"type": "Turbo-fan"
},
"serial_number": "38356",
"type": "Airplane",
"type_designator": "B789"
},
"data_sources": [
"mictronics",
"ca-transport-canada-registry"
],
"icao_hex": "C038AA",
"military": false,
"registrant": {
"administrative_area": "Quebec",
"city": "Saint-Laurent",
"country": "CA",
"names": [
"Air Canada"
],
"postal_code": "H4S1Z3",
"street": [
"7373 de la Cรดte-Vertu Blvd."
],
"type": "Entity"
},
"registration": "C-FVLX"
}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/ca-transport-canada-registry/statistic/{name} (all retained):
| Topic suffix | Value | Format |
|---|---|---|
records_imported | e.g. 271 | Integer as string |
last_run_at | e.g. 2026-07-07T14:32:01.123456+00:00 | ISO 8601 UTC |
last_run_status | Success or Failure | String |
Home Assistant autodiscovery configs are also published (retained) to homeassistant/sensor/SkyFollower_runner_ca_transport_canada_registry_{name}/config for each of the three stats above.