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:
homeassistant/helpers/device_registry.py:322-352
@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
Property Description 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:
homeassistant/helpers/device_registry.py:85-108
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