> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/home-assistant/core/llms.txt
> Use this file to discover all available pages before exploring further.

# Devices

> Understanding device management in Home Assistant Core

Devices represent physical hardware in your smart home. They serve as a logical grouping for related entities and provide a way to organize and manage your smart home components.

## What is a Device?

A device is a physical piece of hardware that can have one or more entities associated with it. For example, a smart thermostat device might have:

* A climate entity for temperature control
* A temperature sensor entity
* A humidity sensor entity
* A battery sensor entity

<Info>
  Devices help organize entities and provide context about the hardware they represent.
</Info>

## Device Registry

The device registry (`homeassistant/helpers/device_registry.py`) maintains information about all devices in Home Assistant. It provides:

* Persistent storage of device information
* Unique device identification
* Device-to-config-entry relationships
* Area assignment
* Device metadata (manufacturer, model, firmware version)

## Device Entry Structure

Each device in the registry has a `DeviceEntry` with the following key attributes:

<CodeGroup>
  ```python homeassistant/helpers/device_registry.py:322-352 theme={null}
  @attr.s(frozen=True, slots=True)
  class DeviceEntry:
      """Device Registry Entry."""

      area_id: str | None = attr.ib(default=None)
      config_entries: set[str] = attr.ib(converter=set, factory=set)
      config_entries_subentries: dict[str, set[str | None]] = attr.ib(factory=dict)
      configuration_url: str | None = attr.ib(default=None)
      connections: set[tuple[str, str]] = attr.ib(
          converter=set, factory=set, validator=_normalize_connections_validator
      )
      created_at: datetime = attr.ib(factory=utcnow)
      disabled_by: DeviceEntryDisabler | None = attr.ib(default=None)
      entry_type: DeviceEntryType | None = attr.ib(default=None)
      hw_version: str | None = attr.ib(default=None)
      id: str = attr.ib(factory=uuid_util.random_uuid_hex)
      identifiers: set[tuple[str, str]] = attr.ib(converter=set, factory=set)
      labels: set[str] = attr.ib(converter=set, factory=set)
      manufacturer: str | None = attr.ib(default=None)
      model: str | None = attr.ib(default=None)
      model_id: str | None = attr.ib(default=None)
      modified_at: datetime = attr.ib(factory=utcnow)
      name_by_user: str | None = attr.ib(default=None)
      name: str | None = attr.ib(default=None)
      primary_config_entry: str | None = attr.ib(default=None)
      serial_number: str | None = attr.ib(default=None)
      sw_version: str | None = attr.ib(default=None)
      via_device_id: str | None = attr.ib(default=None)
  ```
</CodeGroup>

### Key Properties

| Property         | Description                                                          |
| ---------------- | -------------------------------------------------------------------- |
| `id`             | Unique device identifier                                             |
| `identifiers`    | Set of (domain, unique\_id) tuples that identify the device          |
| `connections`    | Set of (connection\_type, connection\_id) tuples (MAC, Zigbee, etc.) |
| `manufacturer`   | Device manufacturer name                                             |
| `model`          | Device model name                                                    |
| `name`           | Device name                                                          |
| `sw_version`     | Software/firmware version                                            |
| `hw_version`     | Hardware version                                                     |
| `config_entries` | Config entries this device belongs to                                |
| `area_id`        | Associated area ID                                                   |
| `via_device_id`  | Parent device (for hub-connected devices)                            |

## Device Identification

Devices are identified using one or both of these methods:

### Identifiers

Domain-specific unique identifiers:

```python theme={null}
identifiers = {("hue", "00:17:88:5E:D3:01")}
```

### Connections

Physical connection identifiers:

```python theme={null}
connections = {
    ("mac", "00:17:88:5e:d3:01"),
    ("zigbee", "00:17:88:01:04:5e:d3:01")
}
```

<Warning>
  MAC addresses in connections are automatically normalized to lowercase with colons as separators.
</Warning>

## DeviceInfo

Integrations provide device information using the `DeviceInfo` TypedDict:

<CodeGroup>
  ```python homeassistant/helpers/device_registry.py:85-108 theme={null}
  class DeviceInfo(TypedDict, total=False):
      """Entity device information for device registry."""

      configuration_url: str | URL | None
      connections: set[tuple[str, str]]
      created_at: str
      default_manufacturer: str
      default_model: str
      default_name: str
      entry_type: DeviceEntryType | None
      identifiers: set[tuple[str, str]]
      manufacturer: str | None
      model: str | None
      model_id: str | None
      modified_at: str
      name: str | None
      serial_number: str | None
      suggested_area: str | None
      sw_version: str | None
      hw_version: str | None
      translation_key: str | None
      translation_placeholders: Mapping[str, str] | None
      via_device: tuple[str, str]
  ```
</CodeGroup>

## Creating or Updating Devices

Devices are typically created automatically when entities are registered, but you can also create them explicitly:

```python theme={null}
from homeassistant.helpers import device_registry as dr

device_registry = dr.async_get(hass)
device = device_registry.async_get_or_create(
    config_entry_id=config_entry.entry_id,
    identifiers={("my_integration", "unique_device_id")},
    manufacturer="Example Manufacturer",
    model="Model 123",
    name="My Device",
    sw_version="1.0.0",
)
```

## Device Types

Devices can have different entry types:

```python theme={null}
class DeviceEntryType(StrEnum):
    """Device entry type."""
    SERVICE = "service"
```

Service devices represent software services rather than physical hardware (e.g., weather services, APIs).

## Device Relationships

### Hub Devices

Devices can be connected through a hub using `via_device`:

```python theme={null}
device_info = DeviceInfo(
    identifiers={("my_integration", "sensor_123")},
    name="Temperature Sensor",
    via_device=("my_integration", "hub_main"),  # Parent hub
)
```

### Area Assignment

Devices can be assigned to areas for logical grouping:

```python theme={null}
device_registry.async_update_device(
    device_id,
    area_id="living_room"
)
```

## Device Disabling

Devices can be disabled through several mechanisms:

```python theme={null}
class DeviceEntryDisabler(StrEnum):
    """What disabled a device entry."""
    CONFIG_ENTRY = "config_entry"
    INTEGRATION = "integration"
    USER = "user"
```

When a device is disabled, all its entities are also disabled.

## Configuration URL

Devices can provide a URL to their configuration interface:

```python theme={null}
device_info = DeviceInfo(
    identifiers={("my_integration", "device_123")},
    configuration_url="http://192.168.1.100",
    # or
    configuration_url="homeassistant://config/integrations/dashboard/add",
)
```

Supported URL schemes:

* `http://`
* `https://`
* `homeassistant://`

## Retrieving Devices

```python theme={null}
from homeassistant.helpers import device_registry as dr

# Get device registry
device_registry = dr.async_get(hass)

# Get device by ID
device = device_registry.async_get(device_id)

# Get device by identifiers or connections
device = device_registry.async_get_device(
    identifiers={("hue", "00:17:88:5E:D3:01")},
    connections={("mac", "00:17:88:5e:d3:01")}
)

# Get devices for a config entry
devices = dr.async_entries_for_config_entry(
    device_registry, config_entry_id
)
```

## Deleted Devices

When devices are removed, they're moved to a deleted devices collection and can be restored if the same device is discovered again:

```python theme={null}
@attr.s(frozen=True, slots=True)
class DeletedDeviceEntry:
    """Deleted Device Registry Entry."""
    area_id: str | None
    config_entries: set[str]
    connections: set[tuple[str, str]]
    identifiers: set[tuple[str, str]]
    orphaned_timestamp: float | None
    # ... other fields
```

## Best Practices

<Card title="Unique Identification" icon="fingerprint">
  Always provide unique identifiers or connections that persist across device resets and Home Assistant restarts.
</Card>

<Card title="Meaningful Names" icon="tag">
  Provide clear manufacturer, model, and device names to help users identify their devices.
</Card>

<Card title="Version Information" icon="code-branch">
  Include software and hardware version information when available for diagnostics and troubleshooting.
</Card>

<Card title="Hub Relationships" icon="sitemap">
  Use `via_device` to properly represent hub-connected devices for better organization.
</Card>

## Connection Types

Common connection types:

```python theme={null}
CONNECTION_BLUETOOTH = "bluetooth"
CONNECTION_NETWORK_MAC = "mac"
CONNECTION_UPNP = "upnp"
CONNECTION_ZIGBEE = "zigbee"
```

## Example: Complete Device Setup

```python theme={null}
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.entity import DeviceInfo

# Create device through entity's device_info
class MySensorEntity(Entity):
    """Example sensor entity."""
    
    @property
    def device_info(self) -> DeviceInfo:
        """Return device information."""
        return DeviceInfo(
            identifiers={("my_integration", self._device_id)},
            name="My Smart Sensor",
            manufacturer="Example Corp",
            model="Sensor Pro 2000",
            sw_version="2.1.0",
            hw_version="1.0",
            serial_number="SN12345",
            configuration_url="http://192.168.1.100",
            suggested_area="Living Room",
        )
```

## Related Resources

<CardGroup cols={2}>
  <Card title="Entities" icon="circle-nodes" href="/concepts/entities">
    Learn about entities and their relationship to devices
  </Card>

  <Card title="Config Entries" icon="file-import" href="/architecture/config-entries">
    Understand how devices relate to config entries
  </Card>
</CardGroup>
