# Devices Context ## Overview Identifies APRS equipment from packet data, maintaining a local registry of known devices. ## Schema: `Aprsme.Devices` (`lib/aprsme/devices.ex`) Stores known APRS device information in the `devices` table: | Field | Type | Notes | |---|---|---| | `identifier` | string | Unique device identifier | | `class` | string | Device class (e.g., "tracker", "handheld") | | `model` | string | Model name | | `vendor` | string | Manufacturer name | | `os` | string | Operating system | | `contact` | string | Vendor/author contact | | `features` | {:array, :string} | Feature tags | No FK constraint: `device_identifier` on the `packets` table is a free-text string, not a DB-level reference. ## DeviceIdentification (`lib/aprsme/device_identification.ex`) ### Static Identification Matches known MIC-E symbol patterns (regex-based) to identify ~20 common device types from packet data. ### Remote Registry Fetches device database from `aprs-deviceid.aprsfoundation.org`: - `maybe_refresh_devices/0` — Weekly refresh cycle - `fetch_and_upsert_devices/0` — HTTP fetch wrapped in `CircuitBreaker`, upserts results into `devices` table - `lookup_device_by_identifier/1` — Wildcard-matching lookup, delegates to `DeviceCache` ### Caching - `DeviceCache` GenServer caches device data, refreshed daily - Backed by `Aprsme.Cache` abstraction ## DeviceParser (`lib/aprsme/device_parser.ex`) Extracts device identifiers from incoming packets by probing: 1. `data_extended.device_identifier` field 2. `destination` field 3. `data_extended.symbol_table_id` + `symbol_code` combination Called during packet ingestion pipeline in `PacketConsumer`. ## Resilience - `CircuitBreaker` wraps remote HTTP fetch, preventing cascading failures - Cache ensures device lookups work even when remote source is unavailable - Static patterns provide fallback identification without network calls