mirror of
https://github.com/home-assistant/core.git
synced 2025-08-15 18:41:44 +02:00
Add subdevices support to ESPHome
This commit is contained in:
@@ -244,9 +244,21 @@ class EsphomeEntity(EsphomeBaseEntity, Generic[_InfoT, _StateT]):
|
||||
self._key = entity_info.key
|
||||
self._state_type = state_type
|
||||
self._on_static_info_update(entity_info)
|
||||
|
||||
# Determine the device connection based on whether this entity belongs to a sub device
|
||||
if entity_info.device_id:
|
||||
# Entity belongs to a sub device
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={
|
||||
(DOMAIN, f"{device_info.mac_address}_{entity_info.device_id}")
|
||||
}
|
||||
)
|
||||
else:
|
||||
# Entity belongs to the main device
|
||||
self._attr_device_info = DeviceInfo(
|
||||
connections={(dr.CONNECTION_NETWORK_MAC, device_info.mac_address)}
|
||||
)
|
||||
|
||||
if entity_info.name:
|
||||
self.entity_id = f"{domain}.{device_info.name}_{entity_info.object_id}"
|
||||
else:
|
||||
|
@@ -751,6 +751,26 @@ def _async_setup_device_registry(
|
||||
device_info = entry_data.device_info
|
||||
if TYPE_CHECKING:
|
||||
assert device_info is not None
|
||||
|
||||
device_registry = dr.async_get(hass)
|
||||
# Build sets of valid device identifiers and connections
|
||||
valid_connections = {(dr.CONNECTION_NETWORK_MAC, device_info.mac_address)}
|
||||
valid_identifiers = {
|
||||
(DOMAIN, f"{device_info.mac_address}_{sub_device.device_id}")
|
||||
for sub_device in device_info.devices
|
||||
}
|
||||
|
||||
# Remove devices that no longer exist
|
||||
for device in dr.async_entries_for_config_entry(device_registry, entry.entry_id):
|
||||
# Skip devices we want to keep
|
||||
if (
|
||||
device.connections & valid_connections
|
||||
or device.identifiers & valid_identifiers
|
||||
):
|
||||
continue
|
||||
# Remove everything else
|
||||
device_registry.async_remove_device(device.id)
|
||||
|
||||
sw_version = device_info.esphome_version
|
||||
if device_info.compilation_time:
|
||||
sw_version += f" ({device_info.compilation_time})"
|
||||
@@ -779,11 +799,14 @@ def _async_setup_device_registry(
|
||||
f"{device_info.project_version} (ESPHome {device_info.esphome_version})"
|
||||
)
|
||||
|
||||
suggested_area = None
|
||||
suggested_area: str | None = None
|
||||
if device_info.suggested_area:
|
||||
suggested_area = device_info.suggested_area
|
||||
elif device_info.area:
|
||||
# Use main device area if suggested_area is not set
|
||||
suggested_area = device_info.area.name
|
||||
|
||||
device_registry = dr.async_get(hass)
|
||||
# Create/update main device
|
||||
device_entry = device_registry.async_get_or_create(
|
||||
config_entry_id=entry.entry_id,
|
||||
configuration_url=configuration_url,
|
||||
@@ -794,6 +817,36 @@ def _async_setup_device_registry(
|
||||
sw_version=sw_version,
|
||||
suggested_area=suggested_area,
|
||||
)
|
||||
|
||||
# Handle sub devices
|
||||
# Find available areas from device_info
|
||||
areas_by_id = {area.area_id: area for area in device_info.areas}
|
||||
# Create/update sub devices that should exist
|
||||
for sub_device in device_info.devices:
|
||||
# Create a unique identifier for this sub device
|
||||
sub_device_identifier = f"{device_info.mac_address}_{sub_device.device_id}"
|
||||
|
||||
# Determine the area for this sub device
|
||||
sub_device_suggested_area: str | None = None
|
||||
if sub_device.area_id and sub_device.area_id in areas_by_id:
|
||||
sub_device_suggested_area = areas_by_id[sub_device.area_id].name
|
||||
|
||||
sub_device_entry = device_registry.async_get_or_create(
|
||||
config_entry_id=entry.entry_id,
|
||||
identifiers={(DOMAIN, sub_device_identifier)},
|
||||
name=sub_device.name,
|
||||
manufacturer=manufacturer,
|
||||
model=model,
|
||||
sw_version=sw_version,
|
||||
suggested_area=sub_device_suggested_area,
|
||||
)
|
||||
|
||||
# Update the sub device to set via_device_id
|
||||
device_registry.async_update_device(
|
||||
sub_device_entry.id,
|
||||
via_device_id=device_entry.id,
|
||||
)
|
||||
|
||||
return device_entry.id
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user