ADR-0008: Bridge (composite) remotes

Status

Accepted

Area

Application model

Context

A single remote sometimes needs to span several physical devices and delivery methods — for example one remote whose buttons reach both a Fire TV (over ADB) and an IR remote (over the blaster). This requires an application model where one remote can route each button to a different saved device of any kind.

Decision

A bridge remote is a vendor:"bridge" SavedDevice with a new routes: BTreeMap<canonical key name, target device id> — deliberately a separate field from the IR overrides map (which stays a key→code-set map for a single IR device). routes maps a button to another saved device of any kind. Commands create_bridge (id bridge:<name>) and set_routes; the store gains Store::set_routes.

Routing reuses the existing send_to_device, no duplicated send logic. The UI send callback special-cases a bridge: look up routes[K.canonical()], find that target in the saved list, call api::send_to_device(&target, K). Because that helper already dispatches IR (overrides→custom_ir→code_set), network backends, and Fire TV ADB per the target’s vendor, a bridge that targets a Fire TV sends over ADB and one targeting an IR remote sends over the blaster — automatically.

The bridge editor picker excludes this bridge, other bridges, and macro/activity devices (they can’t receive a raw key).

Consequences

Because send_to_device already dispatches per the target’s vendor, the correct transport (ADB for a Fire TV target, the blaster for an IR target) is selected automatically with no extra send logic. Unmapped keys are silently ignored (Power routes the same way).