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._key = entity_info.key
|
||||||
self._state_type = state_type
|
self._state_type = state_type
|
||||||
self._on_static_info_update(entity_info)
|
self._on_static_info_update(entity_info)
|
||||||
self._attr_device_info = DeviceInfo(
|
|
||||||
connections={(dr.CONNECTION_NETWORK_MAC, device_info.mac_address)}
|
# 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:
|
if entity_info.name:
|
||||||
self.entity_id = f"{domain}.{device_info.name}_{entity_info.object_id}"
|
self.entity_id = f"{domain}.{device_info.name}_{entity_info.object_id}"
|
||||||
else:
|
else:
|
||||||
|
@@ -751,6 +751,26 @@ def _async_setup_device_registry(
|
|||||||
device_info = entry_data.device_info
|
device_info = entry_data.device_info
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
assert device_info is not None
|
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
|
sw_version = device_info.esphome_version
|
||||||
if device_info.compilation_time:
|
if device_info.compilation_time:
|
||||||
sw_version += f" ({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})"
|
f"{device_info.project_version} (ESPHome {device_info.esphome_version})"
|
||||||
)
|
)
|
||||||
|
|
||||||
suggested_area = None
|
suggested_area: str | None = None
|
||||||
if device_info.suggested_area:
|
if device_info.suggested_area:
|
||||||
suggested_area = 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(
|
device_entry = device_registry.async_get_or_create(
|
||||||
config_entry_id=entry.entry_id,
|
config_entry_id=entry.entry_id,
|
||||||
configuration_url=configuration_url,
|
configuration_url=configuration_url,
|
||||||
@@ -794,6 +817,36 @@ def _async_setup_device_registry(
|
|||||||
sw_version=sw_version,
|
sw_version=sw_version,
|
||||||
suggested_area=suggested_area,
|
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
|
return device_entry.id
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user