mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Use translations for fan_speed in tplink vacuum entity (#136718)
This commit is contained in:
parent
60b6a11d4e
commit
6b4ec3f3f4
@ -110,6 +110,9 @@ class TPLinkModuleEntityDescription(TPLinkEntityDescription):
|
|||||||
unique_id_fn: Callable[[Device, TPLinkModuleEntityDescription], str] = (
|
unique_id_fn: Callable[[Device, TPLinkModuleEntityDescription], str] = (
|
||||||
lambda device, desc: f"{legacy_device_id(device)}-{desc.key}"
|
lambda device, desc: f"{legacy_device_id(device)}-{desc.key}"
|
||||||
)
|
)
|
||||||
|
entity_name_fn: (
|
||||||
|
Callable[[Device, TPLinkModuleEntityDescription], str | None] | None
|
||||||
|
) = None
|
||||||
|
|
||||||
|
|
||||||
def async_refresh_after[_T: CoordinatedTPLinkEntity, **_P](
|
def async_refresh_after[_T: CoordinatedTPLinkEntity, **_P](
|
||||||
@ -550,7 +553,9 @@ class CoordinatedTPLinkModuleEntity(CoordinatedTPLinkEntity, ABC):
|
|||||||
# the description should have a translation key.
|
# the description should have a translation key.
|
||||||
# HA logic is to name entities based on the following logic:
|
# HA logic is to name entities based on the following logic:
|
||||||
# _attr_name > translation.name > description.name
|
# _attr_name > translation.name > description.name
|
||||||
if not description.translation_key:
|
if entity_name_fn := description.entity_name_fn:
|
||||||
|
self._attr_name = entity_name_fn(device, description)
|
||||||
|
elif not description.translation_key:
|
||||||
if parent is None or parent.device_type is Device.Type.Hub:
|
if parent is None or parent.device_type is Device.Type.Hub:
|
||||||
self._attr_name = None
|
self._attr_name = None
|
||||||
else:
|
else:
|
||||||
|
@ -283,6 +283,21 @@
|
|||||||
"clean_count": {
|
"clean_count": {
|
||||||
"name": "Clean count"
|
"name": "Clean count"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"vacuum": {
|
||||||
|
"vacuum": {
|
||||||
|
"state_attributes": {
|
||||||
|
"fan_speed": {
|
||||||
|
"state": {
|
||||||
|
"quiet": "Quiet",
|
||||||
|
"standard": "Standard",
|
||||||
|
"turbo": "Turbo",
|
||||||
|
"max": "Max",
|
||||||
|
"ultra": "Ultra"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"device": {
|
"device": {
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Any, cast
|
from typing import Any
|
||||||
|
|
||||||
from kasa import Device, Feature, Module
|
from kasa import Device, Module
|
||||||
from kasa.smart.modules.clean import Clean, Status
|
from kasa.smart.modules.clean import Clean, Status
|
||||||
|
|
||||||
from homeassistant.components.vacuum import (
|
from homeassistant.components.vacuum import (
|
||||||
@ -52,7 +52,10 @@ class TPLinkVacuumEntityDescription(
|
|||||||
|
|
||||||
VACUUM_DESCRIPTIONS: tuple[TPLinkVacuumEntityDescription, ...] = (
|
VACUUM_DESCRIPTIONS: tuple[TPLinkVacuumEntityDescription, ...] = (
|
||||||
TPLinkVacuumEntityDescription(
|
TPLinkVacuumEntityDescription(
|
||||||
key="vacuum", exists_fn=lambda dev, _: Module.Clean in dev.modules
|
key="vacuum",
|
||||||
|
translation_key="vacuum",
|
||||||
|
exists_fn=lambda dev, _: Module.Clean in dev.modules,
|
||||||
|
entity_name_fn=lambda _, __: None,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -97,7 +100,6 @@ class TPLinkVacuumEntity(CoordinatedTPLinkModuleEntity, StateVacuumEntity):
|
|||||||
| VacuumEntityFeature.START
|
| VacuumEntityFeature.START
|
||||||
| VacuumEntityFeature.PAUSE
|
| VacuumEntityFeature.PAUSE
|
||||||
| VacuumEntityFeature.RETURN_HOME
|
| VacuumEntityFeature.RETURN_HOME
|
||||||
| VacuumEntityFeature.FAN_SPEED
|
|
||||||
)
|
)
|
||||||
|
|
||||||
entity_description: TPLinkVacuumEntityDescription
|
entity_description: TPLinkVacuumEntityDescription
|
||||||
@ -117,8 +119,11 @@ class TPLinkVacuumEntity(CoordinatedTPLinkModuleEntity, StateVacuumEntity):
|
|||||||
self._speaker_module = speaker
|
self._speaker_module = speaker
|
||||||
self._attr_supported_features |= VacuumEntityFeature.LOCATE
|
self._attr_supported_features |= VacuumEntityFeature.LOCATE
|
||||||
|
|
||||||
# Needs to be initialized empty, as vacuumentity's capability_attributes accesses it
|
if (
|
||||||
self._attr_fan_speed_list: list[str] = []
|
fanspeed_feat := self._vacuum_module.get_feature("fan_speed_preset")
|
||||||
|
) and fanspeed_feat.choices:
|
||||||
|
self._attr_supported_features |= VacuumEntityFeature.FAN_SPEED
|
||||||
|
self._attr_fan_speed_list = [c.lower() for c in fanspeed_feat.choices]
|
||||||
|
|
||||||
@async_refresh_after
|
@async_refresh_after
|
||||||
async def async_start(self) -> None:
|
async def async_start(self) -> None:
|
||||||
@ -138,7 +143,7 @@ class TPLinkVacuumEntity(CoordinatedTPLinkModuleEntity, StateVacuumEntity):
|
|||||||
@async_refresh_after
|
@async_refresh_after
|
||||||
async def async_set_fan_speed(self, fan_speed: str, **kwargs: Any) -> None:
|
async def async_set_fan_speed(self, fan_speed: str, **kwargs: Any) -> None:
|
||||||
"""Set fan speed."""
|
"""Set fan speed."""
|
||||||
await self._vacuum_module.set_fan_speed_preset(fan_speed)
|
await self._vacuum_module.set_fan_speed_preset(fan_speed.capitalize())
|
||||||
|
|
||||||
async def async_locate(self, **kwargs: Any) -> None:
|
async def async_locate(self, **kwargs: Any) -> None:
|
||||||
"""Locate the device."""
|
"""Locate the device."""
|
||||||
@ -152,7 +157,6 @@ class TPLinkVacuumEntity(CoordinatedTPLinkModuleEntity, StateVacuumEntity):
|
|||||||
def _async_update_attrs(self) -> bool:
|
def _async_update_attrs(self) -> bool:
|
||||||
"""Update the entity's attributes."""
|
"""Update the entity's attributes."""
|
||||||
self._attr_activity = STATUS_TO_ACTIVITY.get(self._vacuum_module.status)
|
self._attr_activity = STATUS_TO_ACTIVITY.get(self._vacuum_module.status)
|
||||||
fanspeeds = cast(Feature, self._vacuum_module.get_feature("fan_speed_preset"))
|
if self._vacuum_module.has_feature("fan_speed_preset"):
|
||||||
self._attr_fan_speed_list = cast(list[str], fanspeeds.choices)
|
self._attr_fan_speed = self._vacuum_module.fan_speed_preset.lower()
|
||||||
self._attr_fan_speed = self._vacuum_module.fan_speed_preset
|
|
||||||
return True
|
return True
|
||||||
|
@ -106,7 +106,7 @@ async def snapshot_platform(
|
|||||||
if entity_entry.translation_key:
|
if entity_entry.translation_key:
|
||||||
key = f"component.{DOMAIN}.entity.{entity_entry.domain}.{entity_entry.translation_key}.name"
|
key = f"component.{DOMAIN}.entity.{entity_entry.domain}.{entity_entry.translation_key}.name"
|
||||||
single_device_class_translation = False
|
single_device_class_translation = False
|
||||||
if key not in translations and entity_entry.original_device_class:
|
if key not in translations: # No name translation
|
||||||
if entity_entry.original_device_class not in unique_device_classes:
|
if entity_entry.original_device_class not in unique_device_classes:
|
||||||
single_device_class_translation = True
|
single_device_class_translation = True
|
||||||
unique_device_classes.append(entity_entry.original_device_class)
|
unique_device_classes.append(entity_entry.original_device_class)
|
||||||
|
@ -42,8 +42,8 @@
|
|||||||
'area_id': None,
|
'area_id': None,
|
||||||
'capabilities': dict({
|
'capabilities': dict({
|
||||||
'fan_speed_list': list([
|
'fan_speed_list': list([
|
||||||
'Quiet',
|
'quiet',
|
||||||
'Max',
|
'max',
|
||||||
]),
|
]),
|
||||||
}),
|
}),
|
||||||
'config_entry_id': <ANY>,
|
'config_entry_id': <ANY>,
|
||||||
@ -68,7 +68,7 @@
|
|||||||
'platform': 'tplink',
|
'platform': 'tplink',
|
||||||
'previous_unique_id': None,
|
'previous_unique_id': None,
|
||||||
'supported_features': <VacuumEntityFeature: 12916>,
|
'supported_features': <VacuumEntityFeature: 12916>,
|
||||||
'translation_key': None,
|
'translation_key': 'vacuum',
|
||||||
'unique_id': '123456789ABCDEFGH-vacuum',
|
'unique_id': '123456789ABCDEFGH-vacuum',
|
||||||
'unit_of_measurement': None,
|
'unit_of_measurement': None,
|
||||||
})
|
})
|
||||||
@ -78,10 +78,10 @@
|
|||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'battery_icon': 'mdi:battery-charging-100',
|
'battery_icon': 'mdi:battery-charging-100',
|
||||||
'battery_level': 100,
|
'battery_level': 100,
|
||||||
'fan_speed': 'Max',
|
'fan_speed': 'max',
|
||||||
'fan_speed_list': list([
|
'fan_speed_list': list([
|
||||||
'Quiet',
|
'quiet',
|
||||||
'Max',
|
'max',
|
||||||
]),
|
]),
|
||||||
'friendly_name': 'my_vacuum',
|
'friendly_name': 'my_vacuum',
|
||||||
'supported_features': <VacuumEntityFeature: 12916>,
|
'supported_features': <VacuumEntityFeature: 12916>,
|
||||||
|
@ -19,7 +19,11 @@ from homeassistant.components.vacuum import (
|
|||||||
)
|
)
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, Platform
|
from homeassistant.const import ATTR_ENTITY_ID, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
from homeassistant.helpers import (
|
||||||
|
device_registry as dr,
|
||||||
|
entity_registry as er,
|
||||||
|
translation,
|
||||||
|
)
|
||||||
|
|
||||||
from . import DEVICE_ID, _mocked_device, setup_platform_for_device, snapshot_platform
|
from . import DEVICE_ID, _mocked_device, setup_platform_for_device, snapshot_platform
|
||||||
|
|
||||||
@ -59,8 +63,12 @@ async def test_vacuum(
|
|||||||
state = hass.states.get(ENTITY_ID)
|
state = hass.states.get(ENTITY_ID)
|
||||||
assert state.state == VacuumActivity.DOCKED
|
assert state.state == VacuumActivity.DOCKED
|
||||||
|
|
||||||
assert state.attributes[ATTR_FAN_SPEED] == "Max"
|
assert state.attributes[ATTR_FAN_SPEED] == "max"
|
||||||
assert state.attributes[ATTR_BATTERY_LEVEL] == 100
|
assert state.attributes[ATTR_BATTERY_LEVEL] == 100
|
||||||
|
result = translation.async_translate_state(
|
||||||
|
hass, "max", "vacuum", "tplink", "vacuum.state_attributes.fan_speed", None
|
||||||
|
)
|
||||||
|
assert result == "Max"
|
||||||
|
|
||||||
|
|
||||||
async def test_states(
|
async def test_states(
|
||||||
@ -90,7 +98,7 @@ async def test_states(
|
|||||||
SERVICE_SET_FAN_SPEED,
|
SERVICE_SET_FAN_SPEED,
|
||||||
Module.Clean,
|
Module.Clean,
|
||||||
"set_fan_speed_preset",
|
"set_fan_speed_preset",
|
||||||
{ATTR_FAN_SPEED: "Quiet"},
|
{ATTR_FAN_SPEED: "quiet"},
|
||||||
),
|
),
|
||||||
(SERVICE_LOCATE, Module.Speaker, "locate", {}),
|
(SERVICE_LOCATE, Module.Speaker, "locate", {}),
|
||||||
],
|
],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user