Skip to main content
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
Devices help organize entities and provide context about the hardware they represent.

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:
@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)

Key Properties

PropertyDescription
idUnique device identifier
identifiersSet of (domain, unique_id) tuples that identify the device
connectionsSet of (connection_type, connection_id) tuples (MAC, Zigbee, etc.)
manufacturerDevice manufacturer name
modelDevice model name
nameDevice name
sw_versionSoftware/firmware version
hw_versionHardware version
config_entriesConfig entries this device belongs to
area_idAssociated area ID
via_device_idParent device (for hub-connected devices)

Device Identification

Devices are identified using one or both of these methods:

Identifiers

Domain-specific unique identifiers:
identifiers = {("hue", "00:17:88:5E:D3:01")}

Connections

Physical connection identifiers:
connections = {
    ("mac", "00:17:88:5e:d3:01"),
    ("zigbee", "00:17:88:01:04:5e:d3:01")
}
MAC addresses in connections are automatically normalized to lowercase with colons as separators.

DeviceInfo

Integrations provide device information using the DeviceInfo TypedDict:
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]

Creating or Updating Devices

Devices are typically created automatically when entities are registered, but you can also create them explicitly:
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:
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:
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:
device_registry.async_update_device(
    device_id,
    area_id="living_room"
)

Device Disabling

Devices can be disabled through several mechanisms:
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:
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

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:
@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

Unique Identification

Always provide unique identifiers or connections that persist across device resets and Home Assistant restarts.

Meaningful Names

Provide clear manufacturer, model, and device names to help users identify their devices.

Version Information

Include software and hardware version information when available for diagnostics and troubleshooting.

Hub Relationships

Use via_device to properly represent hub-connected devices for better organization.

Connection Types

Common connection types:
CONNECTION_BLUETOOTH = "bluetooth"
CONNECTION_NETWORK_MAC = "mac"
CONNECTION_UPNP = "upnp"
CONNECTION_ZIGBEE = "zigbee"

Example: Complete Device Setup

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",
        )

Entities

Learn about entities and their relationship to devices

Config Entries

Understand how devices relate to config entries

Build docs developers (and LLMs) love