Skip to content

Commit de6d34f

Browse files
arturpragaczfrenck
authored andcommitted
Filter out service type devices in extended analytics (home-assistant#153271)
1 parent 38f9067 commit de6d34f

File tree

2 files changed

+38
-23
lines changed

2 files changed

+38
-23
lines changed

homeassistant/components/analytics/analytics.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -505,14 +505,16 @@ def _domains_from_yaml_config(yaml_configuration: dict[str, Any]) -> set[str]:
505505
DEFAULT_ENTITY_ANALYTICS_CONFIG = EntityAnalyticsModifications()
506506

507507

508-
async def async_devices_payload(hass: HomeAssistant) -> dict:
508+
async def async_devices_payload(hass: HomeAssistant) -> dict: # noqa: C901
509509
"""Return detailed information about entities and devices."""
510510
dev_reg = dr.async_get(hass)
511511
ent_reg = er.async_get(hass)
512512

513513
integration_inputs: dict[str, tuple[list[str], list[str]]] = {}
514514
integration_configs: dict[str, AnalyticsModifications] = {}
515515

516+
removed_devices: set[str] = set()
517+
516518
# Get device list
517519
for device_entry in dev_reg.devices.values():
518520
if not device_entry.primary_config_entry:
@@ -525,6 +527,10 @@ async def async_devices_payload(hass: HomeAssistant) -> dict:
525527
if config_entry is None:
526528
continue
527529

530+
if device_entry.entry_type is dr.DeviceEntryType.SERVICE:
531+
removed_devices.add(device_entry.id)
532+
continue
533+
528534
integration_domain = config_entry.domain
529535

530536
integration_input = integration_inputs.setdefault(integration_domain, ([], []))
@@ -614,11 +620,12 @@ async def async_devices_payload(hass: HomeAssistant) -> dict:
614620
device_config = integration_config.devices.get(device_id, device_config)
615621

616622
if device_config.remove:
623+
removed_devices.add(device_id)
617624
continue
618625

619626
device_entry = dev_reg.devices[device_id]
620627

621-
device_id_mapping[device_entry.id] = (integration_domain, len(devices_info))
628+
device_id_mapping[device_id] = (integration_domain, len(devices_info))
622629

623630
devices_info.append(
624631
{
@@ -669,7 +676,7 @@ async def async_devices_payload(hass: HomeAssistant) -> dict:
669676

670677
entity_entry = ent_reg.entities[entity_id]
671678

672-
entity_state = hass.states.get(entity_entry.entity_id)
679+
entity_state = hass.states.get(entity_id)
673680

674681
entity_info = {
675682
# LIMITATION: `assumed_state` can be overridden by users;
@@ -690,15 +697,19 @@ async def async_devices_payload(hass: HomeAssistant) -> dict:
690697
"unit_of_measurement": entity_entry.unit_of_measurement,
691698
}
692699

693-
if (
694-
((device_id_ := entity_entry.device_id) is not None)
695-
and ((new_device_id := device_id_mapping.get(device_id_)) is not None)
696-
and (new_device_id[0] == integration_domain)
697-
):
698-
device_info = devices_info[new_device_id[1]]
699-
device_info["entities"].append(entity_info)
700-
else:
701-
entities_info.append(entity_info)
700+
if (device_id_ := entity_entry.device_id) is not None:
701+
if device_id_ in removed_devices:
702+
# The device was removed, so we remove the entity too
703+
continue
704+
705+
if (
706+
new_device_id := device_id_mapping.get(device_id_)
707+
) is not None and (new_device_id[0] == integration_domain):
708+
device_info = devices_info[new_device_id[1]]
709+
device_info["entities"].append(entity_info)
710+
continue
711+
712+
entities_info.append(entity_info)
702713

703714
return {
704715
"version": "home-assistant:1",

tests/components/analytics/test_analytics.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,17 +1085,6 @@ async def test_devices_payload_no_entities(
10851085
"sw_version": "test-sw-version",
10861086
"via_device": None,
10871087
},
1088-
{
1089-
"entities": [],
1090-
"entry_type": "service",
1091-
"has_configuration_url": False,
1092-
"hw_version": None,
1093-
"manufacturer": "test-manufacturer",
1094-
"model": None,
1095-
"model_id": "test-model-id",
1096-
"sw_version": None,
1097-
"via_device": None,
1098-
},
10991088
{
11001089
"entities": [],
11011090
"entry_type": None,
@@ -1160,6 +1149,13 @@ async def test_devices_payload_with_entities(
11601149
manufacturer="test-manufacturer",
11611150
model_id="test-model-id",
11621151
)
1152+
device_entry_3 = device_registry.async_get_or_create(
1153+
config_entry_id=mock_config_entry.entry_id,
1154+
identifiers={("device", "3")},
1155+
manufacturer="test-manufacturer",
1156+
model_id="test-model-id",
1157+
entry_type=dr.DeviceEntryType.SERVICE,
1158+
)
11631159

11641160
# First device
11651161

@@ -1209,6 +1205,14 @@ async def test_devices_payload_with_entities(
12091205
device_id=device_entry_2.id,
12101206
)
12111207

1208+
# Third device (service type)
1209+
entity_registry.async_get_or_create(
1210+
domain="light",
1211+
platform="hue",
1212+
unique_id="4",
1213+
device_id=device_entry_3.id,
1214+
)
1215+
12121216
# Entity without device with unit of measurement and state class
12131217
entity_registry.async_get_or_create(
12141218
domain="sensor",

0 commit comments

Comments
 (0)