From 34964942907abd254a7d8743fefe8337a0f6610d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 17 Aug 2025 16:15:02 +0200 Subject: [PATCH] Remove filters from device analytics payload (#150771) --- .../components/analytics/analytics.py | 24 ++---- tests/components/analytics/test_analytics.py | 74 +++++++++++++++++-- 2 files changed, 72 insertions(+), 26 deletions(-) diff --git a/homeassistant/components/analytics/analytics.py b/homeassistant/components/analytics/analytics.py index 0d0f5183566..8b276021d38 100644 --- a/homeassistant/components/analytics/analytics.py +++ b/homeassistant/components/analytics/analytics.py @@ -390,7 +390,6 @@ def _domains_from_yaml_config(yaml_configuration: dict[str, Any]) -> set[str]: async def async_devices_payload(hass: HomeAssistant) -> dict: """Return the devices payload.""" - integrations_without_model_id: set[str] = set() devices: list[dict[str, Any]] = [] dev_reg = dr.async_get(hass) # Devices that need via device info set @@ -400,10 +399,6 @@ async def async_devices_payload(hass: HomeAssistant) -> dict: seen_integrations = set() for device in dev_reg.devices.values(): - # Ignore services - if device.entry_type: - continue - if not device.primary_config_entry: continue @@ -414,13 +409,6 @@ async def async_devices_payload(hass: HomeAssistant) -> dict: seen_integrations.add(config_entry.domain) - if not device.model_id: - integrations_without_model_id.add(config_entry.domain) - continue - - if not device.manufacturer: - continue - new_indexes[device.id] = len(devices) devices.append( { @@ -432,8 +420,10 @@ async def async_devices_payload(hass: HomeAssistant) -> dict: "hw_version": device.hw_version, "has_configuration_url": device.configuration_url is not None, "via_device": None, + "entry_type": device.entry_type.value if device.entry_type else None, } ) + if device.via_device_id: via_devices[device.id] = device.via_device_id @@ -453,15 +443,11 @@ async def async_devices_payload(hass: HomeAssistant) -> dict: for device_info in devices: if integration := integrations.get(device_info["integration"]): device_info["is_custom_integration"] = not integration.is_built_in + # Include version for custom integrations + if not integration.is_built_in and integration.version: + device_info["custom_integration_version"] = str(integration.version) return { "version": "home-assistant:1", - "no_model_id": sorted( - [ - domain - for domain in integrations_without_model_id - if domain in integrations and integrations[domain].is_built_in - ] - ), "devices": devices, } diff --git a/tests/components/analytics/test_analytics.py b/tests/components/analytics/test_analytics.py index 0e14d556620..1ade8eed37e 100644 --- a/tests/components/analytics/test_analytics.py +++ b/tests/components/analytics/test_analytics.py @@ -975,6 +975,7 @@ async def test_submitting_legacy_integrations( assert snapshot == submitted_data +@pytest.mark.usefixtures("enable_custom_integrations") async def test_devices_payload( hass: HomeAssistant, hass_client: ClientSessionGenerator, @@ -984,14 +985,16 @@ async def test_devices_payload( assert await async_setup_component(hass, "analytics", {}) assert await async_devices_payload(hass) == { "version": "home-assistant:1", - "no_model_id": [], "devices": [], } mock_config_entry = MockConfigEntry(domain="hue") mock_config_entry.add_to_hass(hass) - # Normal entry + mock_custom_config_entry = MockConfigEntry(domain="test") + mock_custom_config_entry.add_to_hass(hass) + + # Normal device with all fields device_registry.async_get_or_create( config_entry_id=mock_config_entry.entry_id, identifiers={("device", "1")}, @@ -1005,7 +1008,7 @@ async def test_devices_payload( configuration_url="http://example.com/config", ) - # Ignored because service type + # Service type device device_registry.async_get_or_create( config_entry_id=mock_config_entry.entry_id, identifiers={("device", "2")}, @@ -1014,7 +1017,7 @@ async def test_devices_payload( entry_type=dr.DeviceEntryType.SERVICE, ) - # Ignored because no model id + # Device without model_id no_model_id_config_entry = MockConfigEntry(domain="no_model_id") no_model_id_config_entry.add_to_hass(hass) device_registry.async_get_or_create( @@ -1023,14 +1026,14 @@ async def test_devices_payload( manufacturer="test-manufacturer", ) - # Ignored because no manufacturer + # Device without manufacturer device_registry.async_get_or_create( config_entry_id=mock_config_entry.entry_id, identifiers={("device", "5")}, model_id="test-model-id", ) - # Entry with via device + # Device with via_device reference device_registry.async_get_or_create( config_entry_id=mock_config_entry.entry_id, identifiers={("device", "6")}, @@ -1039,9 +1042,16 @@ async def test_devices_payload( via_device=("device", "1"), ) + # Device from custom integration + device_registry.async_get_or_create( + config_entry_id=mock_custom_config_entry.entry_id, + identifiers={("device", "7")}, + manufacturer="test-manufacturer7", + model_id="test-model-id7", + ) + assert await async_devices_payload(hass) == { "version": "home-assistant:1", - "no_model_id": [], "devices": [ { "manufacturer": "test-manufacturer", @@ -1053,6 +1063,42 @@ async def test_devices_payload( "is_custom_integration": False, "has_configuration_url": True, "via_device": None, + "entry_type": None, + }, + { + "manufacturer": "test-manufacturer", + "model_id": "test-model-id", + "model": None, + "sw_version": None, + "hw_version": None, + "integration": "hue", + "is_custom_integration": False, + "has_configuration_url": False, + "via_device": None, + "entry_type": "service", + }, + { + "manufacturer": "test-manufacturer", + "model_id": None, + "model": None, + "sw_version": None, + "hw_version": None, + "integration": "no_model_id", + "has_configuration_url": False, + "via_device": None, + "entry_type": None, + }, + { + "manufacturer": None, + "model_id": "test-model-id", + "model": None, + "sw_version": None, + "hw_version": None, + "integration": "hue", + "is_custom_integration": False, + "has_configuration_url": False, + "via_device": None, + "entry_type": None, }, { "manufacturer": "test-manufacturer6", @@ -1064,6 +1110,20 @@ async def test_devices_payload( "is_custom_integration": False, "has_configuration_url": False, "via_device": 0, + "entry_type": None, + }, + { + "entry_type": None, + "has_configuration_url": False, + "hw_version": None, + "integration": "test", + "manufacturer": "test-manufacturer7", + "model": None, + "model_id": "test-model-id7", + "sw_version": None, + "via_device": None, + "is_custom_integration": True, + "custom_integration_version": "1.2.3", }, ], }