Skip to content

Guernsey ๐Ÿ‡ฌ๐Ÿ‡ฌ 2-reg Registry โ€‹

Namegg-2reg-registry
CountryGuernsey (Bailiwick of Guernsey)
Registration prefix2-
Data sourcehttps://www.2-reg.com/legislation/register/
FormatPDF (date-encoded filename, discovered via index page)
Run frequencyWeekly (Tuesday, 18: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 index page is scraped to discover the current register PDF (matches /wp-content/uploads/*/Register_*.pdf). Pages whose first line matches a known special-section heading (New Registrations, Deregistrations, Ownership Changes, Registration Changes, Reserved Marks) are skipped. Remaining pages are parsed by grouping extracted words into columns by x-position, since pdfplumber's table detection does not reliably find the column boundaries in this PDF. The boundaries are derived on each page from the header row (the x-position of the first word of each column heading), so they follow the PDF's layout rather than being fixed; a page with no recognisable header row is skipped with a warning. A run that parses no records, or parses records but matches none of them to the Mictronics index, is reported as a failure (non-zero exit, last_run_status of Failure) instead of a successful run with zero records. MSN (serial number) is whitespace-collapsed like manufacturer, model, and owner already are, since a word-position-grouped cell can end up 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 โ€‹

The main register table (all pages before the special sections) has six columns. The special sections at the end of the PDF (New Registrations, Deregistrations, Ownership Changes, Registration Changes, Reserved Marks) are skipped entirely by this runner, but several of them present additional columns not found in the main table; those are listed below too, since they genuinely exist in the source.

Source columnImportedNotes
Registrationโœ…2-prefix; used as the Mictronics lookup key
Aircraft Manufacturerโœ…โ†’ aircraft.manufacturer
Typeโœ…โ†’ aircraft.model
MSNโœ…โ†’ aircraft.serial_number; embedded newlines collapsed to a single space
Registered Ownerโœ…โ†’ registrant.names[0]; privacy placeholders (e.g. (private)) are filtered, not stored
Date of RegistrationโŒParsed but not stored
Deregistered onโŒOnly present in the "Deregistrations" special section; entire page is skipped by this runner
Exported toโŒOnly present in the "Deregistrations" special section; entire page is skipped by this runner
Previous Owner/Charterer by DemiseโŒOnly present in the "Registration Ownership Changes" special section; entire page is skipped by this runner
Ownership ChangedโŒOnly present in the "Registration Ownership Changes" special section; entire page is skipped by this runner
Previous MarksโŒOnly present in the "Registration Changes" special section; entire page is skipped by this runner
Effective dateโŒOnly present in the "Registration Changes" special section; entire page is skipped by this runner
Reserved/Unavailable Registration Marks listโŒThe "All Current Reserved or Unavailable Registration Marks" page is skipped entirely; it is a plain list of marks with no owner/aircraft data

See specs/data-dictionary.yaml (gg-2reg-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 43EC60 | python3 -m json.tool --sort-keys --no-ensure-ascii
json
{
    "aircraft": {
        "manufacturer": "The New Piper Aircraft, Inc",
        "manufacturer_model": "PIPER PA-28-201T/235/236",
        "model": "PA-28-235",
        "serial_number": "28-7210009",
        "type_designator": "P28B"
    },
    "data_sources": [
        "mictronics",
        "gg-2reg-registry"
    ],
    "icao_hex": "43EC60",
    "military": false,
    "registration": "2-GOLD"
}

Note: registrant is entirely absent here โ€” this aircraft's owner is recorded as (private) in the source PDF, which is filtered at write time rather than stored.

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/gg-2reg-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_gg_2reg_registry_{name}/config for each of the three stats above.