Support translating entity names (#88242)
This commit is contained in:
parent
376a6eb82a
commit
cf7e500a8e
9 changed files with 40 additions and 3 deletions
8
.github/workflows/ci.yaml
vendored
8
.github/workflows/ci.yaml
vendored
|
@ -1003,6 +1003,10 @@ jobs:
|
|||
run: |
|
||||
. venv/bin/activate
|
||||
pip install mysqlclient sqlalchemy_utils
|
||||
- name: Compile English translations
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
python3 -m script.translations develop --all
|
||||
- name: Run pytest (partially)
|
||||
timeout-minutes: 20
|
||||
shell: bash
|
||||
|
@ -1107,6 +1111,10 @@ jobs:
|
|||
run: |
|
||||
. venv/bin/activate
|
||||
pip install psycopg2 sqlalchemy_utils
|
||||
- name: Compile English translations
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
python3 -m script.translations develop --all
|
||||
- name: Run pytest (partially)
|
||||
timeout-minutes: 20
|
||||
shell: bash
|
||||
|
|
|
@ -126,7 +126,7 @@ async def async_setup_platform(
|
|||
),
|
||||
DemoSensor(
|
||||
unique_id="sensor_10",
|
||||
name="Thermostat mode",
|
||||
name=None,
|
||||
state="eco",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
state_class=None,
|
||||
|
@ -156,7 +156,7 @@ class DemoSensor(SensorEntity):
|
|||
def __init__(
|
||||
self,
|
||||
unique_id: str,
|
||||
name: str,
|
||||
name: str | None,
|
||||
state: StateType,
|
||||
device_class: SensorDeviceClass,
|
||||
state_class: SensorStateClass | None,
|
||||
|
@ -167,7 +167,10 @@ class DemoSensor(SensorEntity):
|
|||
) -> None:
|
||||
"""Initialize the sensor."""
|
||||
self._attr_device_class = device_class
|
||||
if name is not None:
|
||||
self._attr_name = name
|
||||
else:
|
||||
self._attr_has_entity_name = True
|
||||
self._attr_native_unit_of_measurement = unit_of_measurement
|
||||
self._attr_native_value = state
|
||||
self._attr_state_class = state_class
|
||||
|
|
|
@ -98,6 +98,7 @@
|
|||
},
|
||||
"sensor": {
|
||||
"thermostat_mode": {
|
||||
"name": "Thermostat mode",
|
||||
"state": {
|
||||
"away": "Away",
|
||||
"comfort": "Comfort",
|
||||
|
|
|
@ -319,6 +319,15 @@ class Entity(ABC):
|
|||
"""Return the name of the entity."""
|
||||
if hasattr(self, "_attr_name"):
|
||||
return self._attr_name
|
||||
if self.translation_key is not None and self.has_entity_name:
|
||||
assert self.platform
|
||||
name_translation_key = (
|
||||
f"component.{self.platform.platform_name}.entity.{self.platform.domain}"
|
||||
f".{self.translation_key}.name"
|
||||
)
|
||||
if name_translation_key in self.platform.entity_translations:
|
||||
name: str = self.platform.entity_translations[name_translation_key]
|
||||
return name
|
||||
if hasattr(self, "entity_description"):
|
||||
return self.entity_description.name
|
||||
return None
|
||||
|
|
|
@ -39,6 +39,7 @@ from . import (
|
|||
device_registry as dev_reg,
|
||||
entity_registry as ent_reg,
|
||||
service,
|
||||
translation,
|
||||
)
|
||||
from .device_registry import DeviceRegistry
|
||||
from .entity_registry import EntityRegistry, RegistryEntryDisabler, RegistryEntryHider
|
||||
|
@ -124,6 +125,7 @@ class EntityPlatform:
|
|||
self.entity_namespace = entity_namespace
|
||||
self.config_entry: config_entries.ConfigEntry | None = None
|
||||
self.entities: dict[str, Entity] = {}
|
||||
self.entity_translations: dict[str, Any] = {}
|
||||
self._tasks: list[asyncio.Task[None]] = []
|
||||
# Stop tracking tasks after setup is completed
|
||||
self._setup_complete = False
|
||||
|
@ -276,6 +278,15 @@ class EntityPlatform:
|
|||
hass = self.hass
|
||||
full_name = f"{self.domain}.{self.platform_name}"
|
||||
|
||||
try:
|
||||
self.entity_translations = await translation.async_get_translations(
|
||||
hass, hass.config.language, "entity", {self.platform_name}
|
||||
)
|
||||
except Exception as err: # pylint: disable=broad-exception-caught
|
||||
_LOGGER.debug(
|
||||
"Could not load translations for %s", self.platform_name, exc_info=err
|
||||
)
|
||||
|
||||
logger.info("Setting up %s", full_name)
|
||||
warn_task = hass.loop.call_later(
|
||||
SLOW_SETUP_WARNING,
|
||||
|
|
|
@ -286,6 +286,7 @@ def gen_strings_schema(config: Config, integration: Integration) -> vol.Schema:
|
|||
vol.Optional("entity"): {
|
||||
str: {
|
||||
str: {
|
||||
vol.Optional("name"): cv.string_with_no_html,
|
||||
vol.Optional("state_attributes"): {
|
||||
str: {
|
||||
vol.Optional("name"): cv.string_with_no_html,
|
||||
|
|
|
@ -214,6 +214,7 @@ async def test_setup_get_template_headers_params(hass: HomeAssistant) -> None:
|
|||
},
|
||||
)
|
||||
await async_setup_component(hass, "homeassistant", {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert respx.calls.last.request.headers["Accept"] == CONTENT_TYPE_JSON
|
||||
assert respx.calls.last.request.headers["User-Agent"] == "Mozilla/5.0"
|
||||
|
|
|
@ -318,6 +318,7 @@ async def test_setup_get_templated_headers_params(hass: HomeAssistant) -> None:
|
|||
},
|
||||
)
|
||||
await async_setup_component(hass, "homeassistant", {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert respx.calls.last.request.headers["Accept"] == CONTENT_TYPE_JSON
|
||||
assert respx.calls.last.request.headers["User-Agent"] == "Mozilla/5.0"
|
||||
|
|
|
@ -4748,5 +4748,7 @@ async def test_exclude_attributes(recorder_mock: Recorder, hass: HomeAssistant)
|
|||
states: list[State] = await hass.async_add_executor_job(_fetch_states)
|
||||
assert len(states) > 1
|
||||
for state in states:
|
||||
if state.domain != DOMAIN:
|
||||
continue
|
||||
assert ATTR_OPTIONS not in state.attributes
|
||||
assert ATTR_FRIENDLY_NAME in state.attributes
|
||||
|
|
Loading…
Add table
Reference in a new issue