diff --git a/homeassistant/components/matter/entity.py b/homeassistant/components/matter/entity.py index f0718dead21..a463b123fb6 100644 --- a/homeassistant/components/matter/entity.py +++ b/homeassistant/components/matter/entity.py @@ -124,8 +124,13 @@ class MatterEntity(Entity): and ep.has_attribute(None, entity_info.primary_attribute) ): self._name_postfix = str(self._endpoint.endpoint_id) - if self._platform_translation_key and not self.translation_key: - self._attr_translation_key = self._platform_translation_key + # Always set translation_key for state_attributes translations. + # For primary entities (no postfix), suppress the translated name, + # so only the device name is used. + if self._platform_translation_key and not self.translation_key: + self._attr_translation_key = self._platform_translation_key + if not self._name_postfix: + self._attr_name = None # Matter labels can be used to modify the entity name # by appending the text. diff --git a/tests/components/matter/snapshots/test_climate.ambr b/tests/components/matter/snapshots/test_climate.ambr index 5ef6b6f9c9a..be27ffe9a9e 100644 --- a/tests/components/matter/snapshots/test_climate.ambr +++ b/tests/components/matter/snapshots/test_climate.ambr @@ -37,7 +37,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'thermostat', 'unique_id': '00000000000004D2-0000000000000064-MatterNodeDevice-1-MatterThermostat-513-0', 'unit_of_measurement': None, }) @@ -102,7 +102,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'thermostat', 'unique_id': '00000000000004D2-0000000000000014-MatterNodeDevice-1-MatterThermostat-513-0', 'unit_of_measurement': None, }) @@ -167,7 +167,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'thermostat', 'unique_id': '00000000000004D2-0000000000000021-MatterNodeDevice-1-MatterThermostat-513-0', 'unit_of_measurement': None, }) @@ -232,7 +232,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'thermostat', 'unique_id': '00000000000004D2-000000000000000C-MatterNodeDevice-1-MatterThermostat-513-0', 'unit_of_measurement': None, }) @@ -299,7 +299,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'thermostat', 'unique_id': '00000000000004D2-0000000000000004-MatterNodeDevice-1-MatterThermostat-513-0', 'unit_of_measurement': None, }) @@ -368,7 +368,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'thermostat', 'unique_id': '00000000000004D2-000000000000008F-MatterNodeDevice-5-MatterThermostat-513-0', 'unit_of_measurement': None, }) @@ -437,7 +437,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'thermostat', 'unique_id': '00000000000004D2-0000000000000024-MatterNodeDevice-1-MatterThermostat-513-0', 'unit_of_measurement': None, }) @@ -508,7 +508,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'thermostat', 'unique_id': '00000000000004D2-0000000000000096-MatterNodeDevice-1-MatterThermostat-513-0', 'unit_of_measurement': None, }) @@ -580,7 +580,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'thermostat', 'unique_id': '00000000000004D2-0000000000000004-MatterNodeDevice-1-MatterThermostat-513-0', 'unit_of_measurement': None, }) @@ -647,7 +647,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'thermostat', 'unique_id': '00000000000004D2-000000000000000C-MatterNodeDevice-1-MatterThermostat-513-0', 'unit_of_measurement': None, }) diff --git a/tests/components/matter/snapshots/test_fan.ambr b/tests/components/matter/snapshots/test_fan.ambr index 83f2b1836d1..52d5dcc5f82 100644 --- a/tests/components/matter/snapshots/test_fan.ambr +++ b/tests/components/matter/snapshots/test_fan.ambr @@ -37,7 +37,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'fan', 'unique_id': '00000000000004D2-0000000000000004-MatterNodeDevice-1-MatterFan-514-0', 'unit_of_measurement': None, }) @@ -103,7 +103,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'fan', 'unique_id': '00000000000004D2-000000000000008F-MatterNodeDevice-1-MatterFan-514-0', 'unit_of_measurement': None, }) @@ -172,7 +172,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'fan', 'unique_id': '00000000000004D2-0000000000000049-MatterNodeDevice-1-MatterFan-514-0', 'unit_of_measurement': None, }) @@ -237,7 +237,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'fan', 'unique_id': '00000000000004D2-000000000000001D-MatterNodeDevice-1-MatterFan-514-0', 'unit_of_measurement': None, }) @@ -306,7 +306,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'fan', 'unique_id': '00000000000004D2-0000000000000024-MatterNodeDevice-1-MatterFan-514-0', 'unit_of_measurement': None, }) diff --git a/tests/components/matter/snapshots/test_light.ambr b/tests/components/matter/snapshots/test_light.ambr index 759a221098a..da23798ef34 100644 --- a/tests/components/matter/snapshots/test_light.ambr +++ b/tests/components/matter/snapshots/test_light.ambr @@ -36,7 +36,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'light', 'unique_id': '00000000000004D2-0000000000000001-MatterNodeDevice-1-MatterLight-6-0', 'unit_of_measurement': None, }) @@ -115,7 +115,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'light', 'unique_id': '00000000000004D2-0000000000000001-MatterNodeDevice-1-MatterLight-6-0', 'unit_of_measurement': None, }) @@ -393,7 +393,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'light', 'unique_id': '00000000000004D2-0000000000000001-MatterNodeDevice-1-MatterLight-6-0', 'unit_of_measurement': None, }) @@ -452,7 +452,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'light', 'unique_id': '00000000000004D2-0000000000000024-MatterNodeDevice-1-MatterLight-6-0', 'unit_of_measurement': None, }) @@ -511,7 +511,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'light', 'unique_id': '00000000000004D2-000000000000000E-MatterNodeDevice-1-MatterLight-6-0', 'unit_of_measurement': None, }) @@ -568,7 +568,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'light', 'unique_id': '00000000000004D2-0000000000000001-MatterNodeDevice-1-MatterLight-6-0', 'unit_of_measurement': None, }) @@ -630,7 +630,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'light', 'unique_id': '00000000000004D2-0000000000000001-MatterNodeDevice-1-MatterLight-6-0', 'unit_of_measurement': None, }) @@ -701,7 +701,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'light', 'unique_id': '00000000000004D2-0000000000000001-MatterNodeDevice-1-MatterLight-6-0', 'unit_of_measurement': None, }) @@ -768,7 +768,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'light', 'unique_id': '00000000000004D2-0000000000000008-MatterNodeDevice-1-MatterLight-6-0', 'unit_of_measurement': None, }) diff --git a/tests/components/matter/snapshots/test_lock.ambr b/tests/components/matter/snapshots/test_lock.ambr index 85abc801c69..b983bb1e2d6 100644 --- a/tests/components/matter/snapshots/test_lock.ambr +++ b/tests/components/matter/snapshots/test_lock.ambr @@ -30,7 +30,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'lock', 'unique_id': '00000000000004D2-0000000000000014-MatterNodeDevice-1-MatterLock-257-0', 'unit_of_measurement': None, }) @@ -81,7 +81,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'lock', 'unique_id': '00000000000004D2-0000000000000001-MatterNodeDevice-1-MatterLock-257-0', 'unit_of_measurement': None, }) @@ -132,7 +132,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'lock', 'unique_id': '00000000000004D2-0000000000000001-MatterNodeDevice-1-MatterLock-257-0', 'unit_of_measurement': None, }) @@ -183,7 +183,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'lock', 'unique_id': '00000000000004D2-0000000000000097-MatterNodeDevice-1-MatterLock-257-0', 'unit_of_measurement': None, }) @@ -234,7 +234,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'lock', 'unique_id': '00000000000004D2-0000000000000002-MatterNodeDevice-1-MatterLock-257-0', 'unit_of_measurement': None, }) diff --git a/tests/components/matter/snapshots/test_switch.ambr b/tests/components/matter/snapshots/test_switch.ambr index 2fc485f367b..25e04f62cb1 100644 --- a/tests/components/matter/snapshots/test_switch.ambr +++ b/tests/components/matter/snapshots/test_switch.ambr @@ -130,7 +130,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'switch', 'unique_id': '00000000000004D2-0000000000000053-MatterNodeDevice-1-MatterPlug-6-0', 'unit_of_measurement': None, }) @@ -180,7 +180,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'switch', 'unique_id': '00000000000004D2-00000000000000B7-MatterNodeDevice-1-MatterPlug-6-0', 'unit_of_measurement': None, }) @@ -328,7 +328,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'switch', 'unique_id': '00000000000004D2-0000000000000025-MatterNodeDevice-1-MatterSwitch-6-0', 'unit_of_measurement': None, }) @@ -428,7 +428,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'switch', 'unique_id': '00000000000004D2-0000000000000004-MatterNodeDevice-1-MatterSwitch-6-0', 'unit_of_measurement': None, }) @@ -578,7 +578,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'switch', 'unique_id': '00000000000004D2-0000000000000001-MatterNodeDevice-1-MatterSwitch-6-0', 'unit_of_measurement': None, }) @@ -677,7 +677,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'switch', 'unique_id': '00000000000004D2-0000000000000001-MatterNodeDevice-1-MatterSwitch-6-0', 'unit_of_measurement': None, }) @@ -875,7 +875,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'switch', 'unique_id': '00000000000004D2-0000000000000001-MatterNodeDevice-1-MatterPlug-6-0', 'unit_of_measurement': None, }) @@ -1174,7 +1174,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'switch', 'unique_id': '00000000000004D2-0000000000000001-MatterNodeDevice-1-MatterSwitch-6-0', 'unit_of_measurement': None, }) @@ -1323,7 +1323,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, + 'translation_key': 'switch', 'unique_id': '00000000000004D2-0000000000000004-MatterNodeDevice-1-MatterPlug-6-0', 'unit_of_measurement': None, }) diff --git a/tests/components/matter/snapshots/test_vacuum.ambr b/tests/components/matter/snapshots/test_vacuum.ambr index 7a8adfc8c29..aacdc2525ff 100644 --- a/tests/components/matter/snapshots/test_vacuum.ambr +++ b/tests/components/matter/snapshots/test_vacuum.ambr @@ -30,7 +30,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'vacuum', 'unique_id': '00000000000004D2-000000000000002F-MatterNodeDevice-1-MatterVacuumCleaner-84-1', 'unit_of_measurement': None, }) @@ -80,7 +80,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'vacuum', 'unique_id': '00000000000004D2-0000000000000028-MatterNodeDevice-1-MatterVacuumCleaner-84-1', 'unit_of_measurement': None, }) @@ -130,7 +130,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'vacuum', 'unique_id': '00000000000004D2-0000000000000042-MatterNodeDevice-1-MatterVacuumCleaner-84-1', 'unit_of_measurement': None, }) @@ -180,7 +180,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'vacuum', 'unique_id': '00000000000004D2-0000000000000061-MatterNodeDevice-1-MatterVacuumCleaner-84-1', 'unit_of_measurement': None, }) diff --git a/tests/components/matter/snapshots/test_valve.ambr b/tests/components/matter/snapshots/test_valve.ambr index 7f2262663f0..edb5fe95d96 100644 --- a/tests/components/matter/snapshots/test_valve.ambr +++ b/tests/components/matter/snapshots/test_valve.ambr @@ -30,7 +30,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'valve', 'unique_id': '00000000000004D2-000000000000004B-MatterNodeDevice-1-MatterValve-129-4', 'unit_of_measurement': None, }) diff --git a/tests/components/matter/snapshots/test_water_heater.ambr b/tests/components/matter/snapshots/test_water_heater.ambr index ca80c653a88..b6887097149 100644 --- a/tests/components/matter/snapshots/test_water_heater.ambr +++ b/tests/components/matter/snapshots/test_water_heater.ambr @@ -38,7 +38,7 @@ 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': , - 'translation_key': None, + 'translation_key': 'water_heater', 'unique_id': '00000000000004D2-0000000000000019-MatterNodeDevice-2-MatterWaterHeater-513-18', 'unit_of_measurement': None, }) diff --git a/tests/components/matter/test_adapter.py b/tests/components/matter/test_adapter.py index b2567c1add1..6cc967b0566 100644 --- a/tests/components/matter/test_adapter.py +++ b/tests/components/matter/test_adapter.py @@ -155,18 +155,6 @@ async def test_device_registry_single_node_composed_device( assert len(device_registry.devices) == 1 -@pytest.mark.usefixtures("matter_node") -@pytest.mark.parametrize("node_fixture", ["inovelli_vtm31"]) -async def test_multi_endpoint_name(hass: HomeAssistant) -> None: - """Test that the entity name gets postfixed if the device has multiple primary endpoints.""" - entity_state = hass.states.get("light.inovelli_light_1") - assert entity_state - assert entity_state.name == "Inovelli Light (1)" - entity_state = hass.states.get("light.inovelli_light_6") - assert entity_state - assert entity_state.name == "Inovelli Light (6)" - - async def test_get_clean_name() -> None: """Test get_clean_name helper. diff --git a/tests/components/matter/test_entity.py b/tests/components/matter/test_entity.py new file mode 100644 index 00000000000..5f70d03ed13 --- /dev/null +++ b/tests/components/matter/test_entity.py @@ -0,0 +1,192 @@ +"""Test Matter entity behavior.""" + +from __future__ import annotations + +import pytest + +from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er + + +@pytest.mark.usefixtures("matter_node") +@pytest.mark.parametrize( + ("node_fixture", "entity_id", "expected_translation_key", "expected_name"), + [ + ("mock_onoff_light", "light.mock_onoff_light", "light", "Mock OnOff Light"), + ("mock_door_lock", "lock.mock_door_lock", "lock", "Mock Door Lock"), + ("mock_thermostat", "climate.mock_thermostat", "thermostat", "Mock Thermostat"), + ("mock_valve", "valve.mock_valve", "valve", "Mock Valve"), + ("mock_fan", "fan.mocked_fan_switch", "fan", "Mocked Fan Switch"), + ("eve_energy_plug", "switch.eve_energy_plug", "switch", "Eve Energy Plug"), + ("mock_vacuum_cleaner", "vacuum.mock_vacuum", "vacuum", "Mock Vacuum"), + ( + "silabs_water_heater", + "water_heater.water_heater", + "water_heater", + "Water Heater", + ), + ], +) +async def test_single_endpoint_platform_translation_key( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + entity_id: str, + expected_translation_key: str, + expected_name: str, +) -> None: + """Test single-endpoint entities on platforms with _platform_translation_key. + + The translation key must always be present for state_attributes translations + and icon translations. When there is no endpoint postfix, the entity name + should be suppressed (None) so only the device name is displayed. + """ + entry = entity_registry.async_get(entity_id) + assert entry is not None + assert entry.translation_key == expected_translation_key + # No original_name means the entity name is suppressed, + # so only the device name is shown + assert entry.original_name is None + + state = hass.states.get(entity_id) + assert state is not None + # The friendly name should be just the device name (no entity name appended) + assert state.name == expected_name + + +@pytest.mark.usefixtures("matter_node") +@pytest.mark.parametrize("node_fixture", ["inovelli_vtm31"]) +async def test_multi_endpoint_entity_translation_key( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, +) -> None: + """Test that multi-endpoint entities have a translation key and a name postfix. + + When a device has the same primary attribute on multiple endpoints, + the entity name gets postfixed with the endpoint ID. The translation key + must still always be set for translations. + """ + # Endpoint 1 + entry_1 = entity_registry.async_get("light.inovelli_light_1") + assert entry_1 is not None + assert entry_1.translation_key == "light" + assert entry_1.original_name == "Light (1)" + + state_1 = hass.states.get("light.inovelli_light_1") + assert state_1 is not None + assert state_1.name == "Inovelli Light (1)" + + # Endpoint 6 + entry_6 = entity_registry.async_get("light.inovelli_light_6") + assert entry_6 is not None + assert entry_6.translation_key == "light" + assert entry_6.original_name == "Light (6)" + + state_6 = hass.states.get("light.inovelli_light_6") + assert state_6 is not None + assert state_6.name == "Inovelli Light (6)" + + +@pytest.mark.usefixtures("matter_node") +@pytest.mark.parametrize("node_fixture", ["eve_energy_20ecn4101"]) +async def test_label_modified_entity_translation_key( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, +) -> None: + """Test that label-modified entities have a translation key and a label postfix. + + When a device uses Matter labels to differentiate endpoints, + the entity name gets the label as a postfix. The translation key + must still always be set for translations. + """ + # Top outlet + entry_top = entity_registry.async_get("switch.eve_energy_20ecn4101_switch_top") + assert entry_top is not None + assert entry_top.translation_key == "switch" + assert entry_top.original_name == "Switch (top)" + + state_top = hass.states.get("switch.eve_energy_20ecn4101_switch_top") + assert state_top is not None + assert state_top.name == "Eve Energy 20ECN4101 Switch (top)" + + # Bottom outlet + entry_bottom = entity_registry.async_get( + "switch.eve_energy_20ecn4101_switch_bottom" + ) + assert entry_bottom is not None + assert entry_bottom.translation_key == "switch" + assert entry_bottom.original_name == "Switch (bottom)" + + state_bottom = hass.states.get("switch.eve_energy_20ecn4101_switch_bottom") + assert state_bottom is not None + assert state_bottom.name == "Eve Energy 20ECN4101 Switch (bottom)" + + +@pytest.mark.usefixtures("matter_node") +@pytest.mark.parametrize("node_fixture", ["eve_thermo_v4"]) +async def test_description_translation_key_not_overridden( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, +) -> None: + """Test that a description-level translation key is not overridden. + + When an entity description already sets translation_key (e.g. "child_lock"), + the _platform_translation_key logic should not override it. The entity keeps + its description-level translation key and name. + """ + entry = entity_registry.async_get("switch.eve_thermo_20ebp1701_child_lock") + assert entry is not None + # The description-level translation key should be preserved, not overridden + # by _platform_translation_key ("switch") + assert entry.translation_key == "child_lock" + assert entry.original_name == "Child lock" + + state = hass.states.get("switch.eve_thermo_20ebp1701_child_lock") + assert state is not None + assert state.name == "Eve Thermo 20EBP1701 Child lock" + + +@pytest.mark.usefixtures("matter_node") +@pytest.mark.parametrize("node_fixture", ["air_quality_sensor"]) +async def test_entity_name_from_description_translation_key( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, +) -> None: + """Test entity name derived from an explicit description translation key. + + Sensor entities do not set _platform_translation_key on the platform class. + When the entity description sets translation_key explicitly, the entity name + is derived from that translation key. + """ + entry = entity_registry.async_get( + "sensor.lightfi_aq1_air_quality_sensor_air_quality" + ) + assert entry is not None + assert entry.translation_key == "air_quality" + assert entry.original_name == "Air quality" + + state = hass.states.get("sensor.lightfi_aq1_air_quality_sensor_air_quality") + assert state is not None + assert state.name == "lightfi-aq1-air-quality-sensor Air quality" + + +@pytest.mark.usefixtures("matter_node") +@pytest.mark.parametrize("node_fixture", ["mock_temperature_sensor"]) +async def test_entity_name_from_device_class( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, +) -> None: + """Test entity name derived from device class when no translation key is set. + + Sensor entities do not set _platform_translation_key on the platform class. + When the entity description also has no translation_key, the entity name + is derived from the device class instead. + """ + entry = entity_registry.async_get("sensor.mock_temperature_sensor_temperature") + assert entry is not None + assert entry.translation_key is None + # Name is derived from the device class + assert entry.original_name == "Temperature" + + state = hass.states.get("sensor.mock_temperature_sensor_temperature") + assert state is not None + assert state.name == "Mock Temperature Sensor Temperature"