aprs.me/docs/contexts/devices.md

51 lines
1.9 KiB
Markdown

# 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