# Physical Device Key Format in OpenLogi's TOML Configuration: A Complete Guide

> Learn the physical device key formats in OpenLogi's TOML configuration. Discover receiver slot, stable unit, and direct HID connection formats.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: how-to-guide
- Published: 2026-08-31

---

**Physical device keys in OpenLogi use colon-separated identifiers with three formats: `receiver:aabbccdd:slot:N` for receiver-based devices, `unit:XXXXXXXX` for stable transport-independent identity, and `direct:VVVV:PPPP:unit:XXXXXXXX` for direct HID connections.**

The **physical‑device‑key** is the core identifier that OpenLogi uses to track hardware across different connection methods. This string serves as the table name in your [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml) under the `[devices]` section, ensuring settings persist whether your mouse connects via USB, Bluetooth, or a Logitech receiver. Understanding the format is essential for manual configuration and troubleshooting device recognition issues.

## The Three Key Format Types

OpenLogi implements three distinct physical device key patterns, each defined in [`crates/openlogi-core/src/device_order.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/device_order.rs). The `PhysicalDeviceKey` type handles parsing and validation of these formats.

### Receiver-Based Keys: `receiver:<id>:slot:<n>`

**Receiver-based keys** identify devices discovered through Logitech Unifying or Bolt receivers.

```

receiver:aabbccdd:slot:1

```

- `receiver:` — Fixed prefix indicating discovery via wireless receiver
- `aabbccdd` — 8-digit hexadecimal receiver ID
- `slot:` — Literal separator
- `1` — Logical slot number (0–7) where the device is paired

These keys are **connection-path dependent**. If you move a mouse to a different receiver or switch to USB cable, this key no longer applies.

### Unit-Based Keys: `unit:<id>`

**Unit-based keys** provide the stable, canonical identity for a physical device.

```

unit:6be9d300

```

- `unit:` — Fixed prefix for transport-independent identity
- `6be9d300` — 8-digit hexadecimal value derived from device serial number or generated UUID

This key persists across **all connection methods**—receiver, USB cable, and Bluetooth. The GUI and agent use `unit:` keys for storing per-device settings that follow the hardware regardless of how it connects.

### Direct/Generated Keys: `direct:<vid>:<pid>:unit:<id>`

**Direct keys** identify devices seen on specific raw HID paths, typically USB.

```

direct:046d:c08d:unit:6be9d300

```

- `direct:` — Fixed prefix indicating raw HID transport
- `046d` — Vendor ID (Logitech = `0x046d`)
- `c08d` — Product ID (specific device model)
- `unit:` — Stable identity fragment (may be `00000000` for transient keys)

These keys combine **connection specificity** with **device identity**. The `unit:` portion enables OpenLogi to correlate direct-connected devices with their stable profiles.

### Transient Keys and Placeholders

During device discovery—such as when a wireless mouse is asleep or only its route is known—OpenLogi uses **transient keys**:

```

direct:046d:b023:unit:00000000

```

The `unit:00000000` placeholder resolves to the real unit ID once the device wakes and responds to protocol queries. These runtime-only keys should not appear in saved configuration files.

## Configuration File Structure

Physical device keys appear as quoted table names under `[devices]` in [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml). From [`crates/openlogi-core/src/config.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/config.rs), the configuration loader validates each key against the `PhysicalDeviceKey` format.

```toml

# Selected device shown by default in UI

[selected_device]
selected_device = "unit:6be9d300"

# Receiver-specific settings (overrides when on this receiver)

[devices."receiver:a1b2c3d4:slot:2"]
custom_name = "Gaming Mouse"
dpi = 1600
dpi_presets = [800, 1600, 3200]

# Unit-level settings (persist across all connections)

[devices."unit:6be9d300"]
thumbwheel_sensitivity = 20
scroll_resolution = "high"

# Deep-keyed table example

[devices."direct:046d:c08d:unit:6be9d300".bindings]
Back = "BrowserBack"

```

## Parsing Implementation Details

The `PhysicalDeviceKey` struct in [`crates/openlogi-core/src/device_order.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/device_order.rs) enforces format validation:

```rust
pub struct PhysicalDeviceKey(String);

impl PhysicalDeviceKey {
    /// Parses a physical‑device‑key string.
    /// Returns `None` if the format does not match any known pattern.
    pub fn parse(s: &str) -> Option<Self> {
        // Accepts "receiver:…", "unit:…", "direct:…", etc.
        // Full regex implementation in source file
        if s.starts_with("receiver:")
            || s.starts_with("unit:")
            || s.starts_with("direct:")
        {
            Some(PhysicalDeviceKey(s.to_owned()))
        } else {
            None
        }
    }
}

```

**Parsing rules enforced:**
- Keys must start with recognized prefix (`receiver:`, `unit:`, `direct:`, or transport-specific variants)
- Colon-separated components follow prefix-specific patterns
- `unit:` fragment (when present) is extracted as the canonical identifier

## Common Configuration Mistakes

Avoid these errors when editing [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml) manually:

- **Inventing model-only identifiers** — Keys like `2b042` are invalid; every key must reflect a physical device instance, not just the model number
- **Using transient keys permanently** — `unit:00000000` placeholders should be replaced with resolved values
- **Incorrect quoting** — Keys with colons must use quoted table syntax: `[devices."unit:6be9d300"]`, not `[devices.unit:6be9d300]`

The GUI writes correct keys automatically. For manual edits, copy from existing valid entries in your [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml) rather than constructing keys from device labels.

## Reference: Key File Locations

| File | Purpose |
|------|---------|
| [`docs/CONFIGURATION.md`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/CONFIGURATION.md) | Complete TOML schema documentation |
| [`docs/config.example.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/config.example.toml) | Populated example with realistic keys |
| [`crates/openlogi-core/src/device_order.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/device_order.rs) | `PhysicalDeviceKey` type and parsing |
| [`crates/openlogi-core/src/config.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/config.rs) | Configuration loading and validation |

## Summary

- **Physical device keys** are colon-separated identifiers that serve as table names in OpenLogi's [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml)
- **Three formats exist**: `receiver:` for wireless receiver paths, `unit:` for stable device identity, and `direct:` for raw HID connections with embedded unit identity
- **The `unit:` fragment** provides transport-independent persistence for device settings
- **Parsing is implemented** in [`crates/openlogi-core/src/device_order.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/device_order.rs) via the `PhysicalDeviceKey` type
- **Manual configuration** should reuse existing valid keys from [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml); do not invent model-only identifiers

## Frequently Asked Questions

### What happens if I use the wrong physical device key format?

OpenLogi's configuration loader in [`crates/openlogi-core/src/config.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/config.rs) validates keys against the `PhysicalDeviceKey` parser. Invalid keys cause the configuration to fail loading, with errors logged indicating which table name could not be parsed. The device will not receive its custom settings, falling back to defaults.

### Can I use a receiver key and unit key for the same device?

Yes. OpenLogi merges settings hierarchically: **receiver-specific** tables override **unit-level** defaults when that connection path is active. Define base settings under `[devices."unit:XXXXXXXX"]` and connection-specific overrides under `[devices."receiver:XXXXXXXX:slot:N"]`.

### Why does my device key show `unit:00000000`?

This transient placeholder appears when OpenLogi detects a device's connection path but has not yet queried its stable unit identity—common with sleeping wireless devices. The key updates to the real `unit:` value once the device awakens and responds to protocol initialization. Save configuration only after keys resolve to permanent values.

### Where do I find the correct physical device key for my hardware?

Run OpenLogi with your device connected; the GUI or agent writes resolved keys to [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml) automatically. Alternatively, examine [`docs/config.example.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/config.example.toml) for format patterns matching your connection type, then verify against actual entries written by the application.