Filter out service type devices in extended analytics (#153271)

This commit is contained in:
Artur Pragacz
2025-10-01 12:38:50 +02:00
committed by GitHub
parent 07da0cfb2b
commit 7c93d91bae
2 changed files with 38 additions and 23 deletions

View File

@@ -505,7 +505,7 @@ DEFAULT_DEVICE_ANALYTICS_CONFIG = DeviceAnalyticsModifications()
DEFAULT_ENTITY_ANALYTICS_CONFIG = EntityAnalyticsModifications()
async def async_devices_payload(hass: HomeAssistant) -> dict:
async def async_devices_payload(hass: HomeAssistant) -> dict: # noqa: C901
"""Return detailed information about entities and devices."""
dev_reg = dr.async_get(hass)
ent_reg = er.async_get(hass)
@@ -513,6 +513,8 @@ async def async_devices_payload(hass: HomeAssistant) -> dict:
integration_inputs: dict[str, tuple[list[str], list[str]]] = {}
integration_configs: dict[str, AnalyticsModifications] = {}
removed_devices: set[str] = set()
# Get device list
for device_entry in dev_reg.devices.values():
if not device_entry.primary_config_entry:
@@ -525,6 +527,10 @@ async def async_devices_payload(hass: HomeAssistant) -> dict:
if config_entry is None:
continue
if device_entry.entry_type is dr.DeviceEntryType.SERVICE:
removed_devices.add(device_entry.id)
continue
integration_domain = config_entry.domain
integration_input = integration_inputs.setdefault(integration_domain, ([], []))
@@ -614,11 +620,12 @@ async def async_devices_payload(hass: HomeAssistant) -> dict:
device_config = integration_config.devices.get(device_id, device_config)
if device_config.remove:
removed_devices.add(device_id)
continue
device_entry = dev_reg.devices[device_id]
device_id_mapping[device_entry.id] = (integration_domain, len(devices_info))
device_id_mapping[device_id] = (integration_domain, len(devices_info))
devices_info.append(
{
@@ -669,7 +676,7 @@ async def async_devices_payload(hass: HomeAssistant) -> dict:
entity_entry = ent_reg.entities[entity_id]
entity_state = hass.states.get(entity_entry.entity_id)
entity_state = hass.states.get(entity_id)
entity_info = {
# LIMITATION: `assumed_state` can be overridden by users;
@@ -690,14 +697,18 @@ async def async_devices_payload(hass: HomeAssistant) -> dict:
"unit_of_measurement": entity_entry.unit_of_measurement,
}
if (device_id_ := entity_entry.device_id) is not None:
if device_id_ in removed_devices:
# The device was removed, so we remove the entity too
continue
if (
((device_id_ := entity_entry.device_id) is not None)
and ((new_device_id := device_id_mapping.get(device_id_)) is not None)
and (new_device_id[0] == integration_domain)
):
new_device_id := device_id_mapping.get(device_id_)
) is not None and (new_device_id[0] == integration_domain):
device_info = devices_info[new_device_id[1]]
device_info["entities"].append(entity_info)
else:
continue
entities_info.append(entity_info)
return {

View File

@@ -1085,17 +1085,6 @@ async def test_devices_payload_no_entities(
"sw_version": "test-sw-version",
"via_device": None,
},
{
"entities": [],
"entry_type": "service",
"has_configuration_url": False,
"hw_version": None,
"manufacturer": "test-manufacturer",
"model": None,
"model_id": "test-model-id",
"sw_version": None,
"via_device": None,
},
{
"entities": [],
"entry_type": None,
@@ -1160,6 +1149,13 @@ async def test_devices_payload_with_entities(
manufacturer="test-manufacturer",
model_id="test-model-id",
)
device_entry_3 = device_registry.async_get_or_create(
config_entry_id=mock_config_entry.entry_id,
identifiers={("device", "3")},
manufacturer="test-manufacturer",
model_id="test-model-id",
entry_type=dr.DeviceEntryType.SERVICE,
)
# First device
@@ -1209,6 +1205,14 @@ async def test_devices_payload_with_entities(
device_id=device_entry_2.id,
)
# Third device (service type)
entity_registry.async_get_or_create(
domain="light",
platform="hue",
unique_id="4",
device_id=device_entry_3.id,
)
# Entity without device with unit of measurement and state class
entity_registry.async_get_or_create(
domain="sensor",