ScanScreen.lookupCode tried getMetersByScannerCode first and let its thrown
error-envelope abort the whole lookup, so the getMetersByZoneName fallback never
ran; it also sent ZoneName in the scanned case (the API is case-sensitive — the
official app lowercases). Confirmed via live mitmproxy capture of the official
app: a scanned code resolves through ScannerCode, and ZoneName=dl (lowercase)
returns the zone.
Now tries ScannerCode -> ZoneName -> zonename(lowercased) -> TerminalSerNo, each
independent and non-fatal; only reports "Lookup failed" if every attempt errored.
Adds docs/zone-qr/ with the DL-Sandpoint QR (encodes ScannerCode "DL", works in
both BigBrainParking and the official app) and a how-to.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>