From 47efb687808c1fd21b1cc3f1f68a6934865575cb Mon Sep 17 00:00:00 2001 From: Shay Levy Date: Fri, 24 Jan 2025 15:13:10 +0200 Subject: [PATCH] Add missing translations for LG webOS TV and fix names (#136438) --- homeassistant/components/webostv/__init__.py | 27 +++------------ .../components/webostv/config_flow.py | 6 ++-- homeassistant/components/webostv/const.py | 2 +- .../components/webostv/device_trigger.py | 2 +- .../components/webostv/diagnostics.py | 2 +- homeassistant/components/webostv/helpers.py | 33 ++++++++++++++++--- .../components/webostv/media_player.py | 20 ++++++----- homeassistant/components/webostv/notify.py | 4 +-- homeassistant/components/webostv/strings.json | 13 ++++++-- homeassistant/components/webostv/trigger.py | 10 ++++-- .../components/webostv/triggers/__init__.py | 2 +- .../components/webostv/triggers/turn_on.py | 2 +- tests/components/webostv/__init__.py | 2 +- tests/components/webostv/conftest.py | 2 +- tests/components/webostv/const.py | 2 +- tests/components/webostv/test_config_flow.py | 2 +- .../components/webostv/test_device_trigger.py | 3 +- tests/components/webostv/test_diagnostics.py | 2 +- tests/components/webostv/test_media_player.py | 11 ++++--- tests/components/webostv/test_notify.py | 2 +- tests/components/webostv/test_trigger.py | 18 ++++------ 21 files changed, 92 insertions(+), 75 deletions(-) diff --git a/homeassistant/components/webostv/__init__.py b/homeassistant/components/webostv/__init__.py index 6546f9aa0f0..c1a1c698f92 100644 --- a/homeassistant/components/webostv/__init__.py +++ b/homeassistant/components/webostv/__init__.py @@ -1,14 +1,12 @@ -"""Support for LG webOS Smart TV.""" +"""The LG webOS TV integration.""" from __future__ import annotations from contextlib import suppress -import logging from aiowebostv import WebOsClient, WebOsTvPairError from homeassistant.components import notify as hass_notify -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_CLIENT_SECRET, CONF_HOST, @@ -29,17 +27,13 @@ from .const import ( PLATFORMS, WEBOSTV_EXCEPTIONS, ) +from .helpers import WebOsTvConfigEntry, update_client_key CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) -_LOGGER = logging.getLogger(__name__) - -type WebOsTvConfigEntry = ConfigEntry[WebOsClient] - - async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: - """Set up the LG WebOS TV platform.""" + """Set up the LG webOS TV platform.""" hass.data.setdefault(DOMAIN, {DATA_HASS_CONFIG: config}) return True @@ -62,7 +56,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: WebOsTvConfigEntry) -> b # If pairing request accepted there will be no error # Update the stored key without triggering reauth - update_client_key(hass, entry, client) + update_client_key(hass, entry) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) @@ -99,19 +93,6 @@ async def async_update_options(hass: HomeAssistant, entry: WebOsTvConfigEntry) - await hass.config_entries.async_reload(entry.entry_id) -def update_client_key( - hass: HomeAssistant, entry: ConfigEntry, client: WebOsClient -) -> None: - """Check and update stored client key if key has changed.""" - host = entry.data[CONF_HOST] - key = entry.data[CONF_CLIENT_SECRET] - - if client.client_key != key: - _LOGGER.debug("Updating client key for host %s", host) - data = {CONF_HOST: host, CONF_CLIENT_SECRET: client.client_key} - hass.config_entries.async_update_entry(entry, data=data) - - async def async_unload_entry(hass: HomeAssistant, entry: WebOsTvConfigEntry) -> bool: """Unload a config entry.""" if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): diff --git a/homeassistant/components/webostv/config_flow.py b/homeassistant/components/webostv/config_flow.py index 1561a56defe..fbc3eb958dd 100644 --- a/homeassistant/components/webostv/config_flow.py +++ b/homeassistant/components/webostv/config_flow.py @@ -1,4 +1,4 @@ -"""Config flow to configure webostv component.""" +"""Config flow for LG webOS TV integration.""" from __future__ import annotations @@ -35,7 +35,7 @@ DATA_SCHEMA = vol.Schema( async def async_control_connect( hass: HomeAssistant, host: str, key: str | None ) -> WebOsClient: - """Create LG WebOS client and connect to the TV.""" + """Create LG webOS client and connect to the TV.""" client = WebOsClient( host, key, @@ -48,7 +48,7 @@ async def async_control_connect( class FlowHandler(ConfigFlow, domain=DOMAIN): - """WebosTV configuration flow.""" + """LG webOS TV configuration flow.""" VERSION = 1 diff --git a/homeassistant/components/webostv/const.py b/homeassistant/components/webostv/const.py index 9c85c4cf5ac..e505611db52 100644 --- a/homeassistant/components/webostv/const.py +++ b/homeassistant/components/webostv/const.py @@ -1,4 +1,4 @@ -"""Constants used for LG webOS Smart TV.""" +"""Constants for the LG webOS TV integration.""" import asyncio diff --git a/homeassistant/components/webostv/device_trigger.py b/homeassistant/components/webostv/device_trigger.py index 3021cc18ea5..951c11525b1 100644 --- a/homeassistant/components/webostv/device_trigger.py +++ b/homeassistant/components/webostv/device_trigger.py @@ -1,4 +1,4 @@ -"""Provides device automations for control of LG webOS Smart TV.""" +"""Provides device automations for control of LG webOS TV.""" from __future__ import annotations diff --git a/homeassistant/components/webostv/diagnostics.py b/homeassistant/components/webostv/diagnostics.py index d5e2dac06dc..7fb64a2cb8f 100644 --- a/homeassistant/components/webostv/diagnostics.py +++ b/homeassistant/components/webostv/diagnostics.py @@ -1,4 +1,4 @@ -"""Diagnostics support for LG webOS Smart TV.""" +"""Diagnostics support for LG webOS TV.""" from __future__ import annotations diff --git a/homeassistant/components/webostv/helpers.py b/homeassistant/components/webostv/helpers.py index 389c866ba14..3c509a56d1e 100644 --- a/homeassistant/components/webostv/helpers.py +++ b/homeassistant/components/webostv/helpers.py @@ -1,17 +1,24 @@ -"""Helper functions for webOS Smart TV.""" +"""Helper functions for LG webOS TV.""" from __future__ import annotations +import logging + from aiowebostv import WebOsClient -from homeassistant.config_entries import ConfigEntryState +from homeassistant.config_entries import ConfigEntry, ConfigEntryState +from homeassistant.const import CONF_CLIENT_SECRET, CONF_HOST from homeassistant.core import HomeAssistant, callback +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.device_registry import DeviceEntry -from . import WebOsTvConfigEntry from .const import DOMAIN, LIVE_TV_APP_ID +_LOGGER = logging.getLogger(__name__) + +type WebOsTvConfigEntry = ConfigEntry[WebOsClient] + @callback def async_get_device_entry_by_device_id( @@ -32,7 +39,7 @@ def async_get_device_entry_by_device_id( def async_get_device_id_from_entity_id(hass: HomeAssistant, entity_id: str) -> str: """Get device ID from an entity ID. - Raises ValueError if entity or device ID is invalid. + Raises HomeAssistantError if entity or device ID is invalid. """ ent_reg = er.async_get(hass) entity_entry = ent_reg.async_get(entity_id) @@ -42,7 +49,11 @@ def async_get_device_id_from_entity_id(hass: HomeAssistant, entity_id: str) -> s or entity_entry.device_id is None or entity_entry.platform != DOMAIN ): - raise ValueError(f"Entity {entity_id} is not a valid {DOMAIN} entity.") + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="invalid_entity_id", + translation_placeholders={"entity_id": entity_id}, + ) return entity_entry.device_id @@ -91,3 +102,15 @@ def get_sources(client: WebOsClient) -> list[str]: # Preserve order when filtering duplicates return list(dict.fromkeys(sources)) + + +def update_client_key(hass: HomeAssistant, entry: WebOsTvConfigEntry) -> None: + """Check and update stored client key if key has changed.""" + client: WebOsClient = entry.runtime_data + host = entry.data[CONF_HOST] + key = entry.data[CONF_CLIENT_SECRET] + + if client.client_key != key: + _LOGGER.debug("Updating client key for host %s", host) + data = {CONF_HOST: host, CONF_CLIENT_SECRET: client.client_key} + hass.config_entries.async_update_entry(entry, data=data) diff --git a/homeassistant/components/webostv/media_player.py b/homeassistant/components/webostv/media_player.py index 1f280ddfc79..4b39841e29d 100644 --- a/homeassistant/components/webostv/media_player.py +++ b/homeassistant/components/webostv/media_player.py @@ -1,4 +1,4 @@ -"""Support for interface with an LG webOS Smart TV.""" +"""Support for interface with an LG webOS TV.""" from __future__ import annotations @@ -33,7 +33,6 @@ from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.trigger import PluggableAction from homeassistant.helpers.typing import VolDictType -from . import WebOsTvConfigEntry, update_client_key from .const import ( ATTR_BUTTON, ATTR_PAYLOAD, @@ -46,6 +45,7 @@ from .const import ( SERVICE_SELECT_SOUND_OUTPUT, WEBOSTV_EXCEPTIONS, ) +from .helpers import WebOsTvConfigEntry, update_client_key from .triggers.turn_on import async_get_turn_on_trigger _LOGGER = logging.getLogger(__name__) @@ -89,7 +89,7 @@ async def async_setup_entry( entry: WebOsTvConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: - """Set up the LG webOS Smart TV platform.""" + """Set up the LG webOS TV platform.""" platform = entity_platform.async_get_current_platform() for service_name, schema, method in SERVICES: @@ -132,7 +132,7 @@ def cmd[_T: LgWebOSMediaPlayerEntity, **_P]( class LgWebOSMediaPlayerEntity(RestoreEntity, MediaPlayerEntity): - """Representation of a LG webOS Smart TV.""" + """Representation of a LG webOS TV.""" _attr_device_class = MediaPlayerDeviceClass.TV _attr_has_entity_name = True @@ -335,7 +335,7 @@ class LgWebOSMediaPlayerEntity(RestoreEntity, MediaPlayerEntity): except WebOsTvPairError: self._entry.async_start_reauth(self.hass) else: - update_client_key(self.hass, self._entry, self._client) + update_client_key(self.hass, self._entry) @property def supported_features(self) -> MediaPlayerEntityFeature: @@ -392,10 +392,14 @@ class LgWebOSMediaPlayerEntity(RestoreEntity, MediaPlayerEntity): async def async_select_source(self, source: str) -> None: """Select input source.""" if (source_dict := self._source_list.get(source)) is None: - _LOGGER.warning( - "Source %s not found for %s", source, self._friendly_name_internal() + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="source_not_found", + translation_placeholders={ + "source": source, + "name": str(self._friendly_name_internal()), + }, ) - return if source_dict.get("title"): await self._client.launch_app(source_dict["id"]) elif source_dict.get("label"): diff --git a/homeassistant/components/webostv/notify.py b/homeassistant/components/webostv/notify.py index dbd79363198..2393cb4cd07 100644 --- a/homeassistant/components/webostv/notify.py +++ b/homeassistant/components/webostv/notify.py @@ -1,4 +1,4 @@ -"""Support for LG WebOS TV notification service.""" +"""Support for LG webOS TV notification service.""" from __future__ import annotations @@ -37,7 +37,7 @@ async def async_get_service( class LgWebOSNotificationService(BaseNotificationService): - """Implement the notification service for LG WebOS TV.""" + """Implement the notification service for LG webOS TV.""" def __init__(self, entry: WebOsTvConfigEntry) -> None: """Initialize the service.""" diff --git a/homeassistant/components/webostv/strings.json b/homeassistant/components/webostv/strings.json index 54cc8dbe230..f6d033af632 100644 --- a/homeassistant/components/webostv/strings.json +++ b/homeassistant/components/webostv/strings.json @@ -12,7 +12,7 @@ } }, "pairing": { - "title": "webOS TV Pairing", + "title": "LG webOS TV Pairing", "description": "Select **Submit** and accept the pairing request on your TV.\n\n![Image](/static/images/config_webos.png)" }, "reauth_confirm": { @@ -43,7 +43,7 @@ "options": { "step": { "init": { - "title": "Options for webOS Smart TV", + "title": "Options for LG webOS TV", "description": "Select enabled sources", "data": { "sources": "Sources list" @@ -129,6 +129,15 @@ }, "unhandled_trigger_type": { "message": "Unhandled trigger type: {trigger_type}" + }, + "unknown_trigger_platform": { + "message": "Unknown trigger platform: {platform}" + }, + "invalid_entity_id": { + "message": "Entity {entity_id} is not a valid webostv entity." + }, + "source_not_found": { + "message": "Source {source} not found in the sources list for {name}." } } } diff --git a/homeassistant/components/webostv/trigger.py b/homeassistant/components/webostv/trigger.py index 3290aa4a448..f121daafb91 100644 --- a/homeassistant/components/webostv/trigger.py +++ b/homeassistant/components/webostv/trigger.py @@ -1,4 +1,4 @@ -"""webOS Smart TV trigger dispatcher.""" +"""LG webOS TV trigger dispatcher.""" from __future__ import annotations @@ -6,6 +6,7 @@ from typing import cast from homeassistant.const import CONF_PLATFORM from homeassistant.core import CALLBACK_TYPE, HomeAssistant +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.trigger import ( TriggerActionType, TriggerInfo, @@ -13,6 +14,7 @@ from homeassistant.helpers.trigger import ( ) from homeassistant.helpers.typing import ConfigType +from .const import DOMAIN from .triggers import turn_on TRIGGERS = { @@ -24,8 +26,10 @@ def _get_trigger_platform(config: ConfigType) -> TriggerProtocol: """Return trigger platform.""" platform_split = config[CONF_PLATFORM].split(".", maxsplit=1) if len(platform_split) < 2 or platform_split[1] not in TRIGGERS: - raise ValueError( - f"Unknown webOS Smart TV trigger platform {config[CONF_PLATFORM]}" + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="unknown_trigger_platform", + translation_placeholders={"platform": config[CONF_PLATFORM]}, ) return cast(TriggerProtocol, TRIGGERS[platform_split[1]]) diff --git a/homeassistant/components/webostv/triggers/__init__.py b/homeassistant/components/webostv/triggers/__init__.py index d8c5a28ef3f..89bdf5f90ee 100644 --- a/homeassistant/components/webostv/triggers/__init__.py +++ b/homeassistant/components/webostv/triggers/__init__.py @@ -1 +1 @@ -"""webOS Smart TV triggers.""" +"""LG webOS TV triggers.""" diff --git a/homeassistant/components/webostv/triggers/turn_on.py b/homeassistant/components/webostv/triggers/turn_on.py index f2ecb8aa98d..648da690715 100644 --- a/homeassistant/components/webostv/triggers/turn_on.py +++ b/homeassistant/components/webostv/triggers/turn_on.py @@ -1,4 +1,4 @@ -"""webOS Smart TV device turn on trigger.""" +"""LG webOS TV device turn on trigger.""" from __future__ import annotations diff --git a/tests/components/webostv/__init__.py b/tests/components/webostv/__init__.py index 5027b235eb1..d9a0a135023 100644 --- a/tests/components/webostv/__init__.py +++ b/tests/components/webostv/__init__.py @@ -1,4 +1,4 @@ -"""Tests for the WebOS TV integration.""" +"""Tests for the LG webOS TV integration.""" from homeassistant.components.webostv.const import DOMAIN from homeassistant.const import CONF_CLIENT_SECRET, CONF_HOST diff --git a/tests/components/webostv/conftest.py b/tests/components/webostv/conftest.py index 711d400b0e6..bf007f5b936 100644 --- a/tests/components/webostv/conftest.py +++ b/tests/components/webostv/conftest.py @@ -1,4 +1,4 @@ -"""Common fixtures and objects for the LG webOS integration tests.""" +"""Common fixtures and objects for the LG webOS TV integration tests.""" from collections.abc import Generator from unittest.mock import AsyncMock, Mock, patch diff --git a/tests/components/webostv/const.py b/tests/components/webostv/const.py index 52453d4ffa9..a63a4fe3289 100644 --- a/tests/components/webostv/const.py +++ b/tests/components/webostv/const.py @@ -1,4 +1,4 @@ -"""Constants for LG webOS Smart TV tests.""" +"""Constants for LG webOS TV tests.""" from homeassistant.components.media_player import DOMAIN as MP_DOMAIN from homeassistant.components.webostv.const import LIVE_TV_APP_ID diff --git a/tests/components/webostv/test_config_flow.py b/tests/components/webostv/test_config_flow.py index 0d8b86b4ac2..34ab39618d8 100644 --- a/tests/components/webostv/test_config_flow.py +++ b/tests/components/webostv/test_config_flow.py @@ -1,4 +1,4 @@ -"""Test the WebOS Tv config flow.""" +"""Test the LG webOS TV config flow.""" from aiowebostv import WebOsTvPairError import pytest diff --git a/tests/components/webostv/test_device_trigger.py b/tests/components/webostv/test_device_trigger.py index 1995897e079..c14e8f4542a 100644 --- a/tests/components/webostv/test_device_trigger.py +++ b/tests/components/webostv/test_device_trigger.py @@ -1,4 +1,4 @@ -"""The tests for WebOS TV device triggers.""" +"""The tests for LG webOS TV device triggers.""" import pytest @@ -140,7 +140,6 @@ async def test_invalid_entry_raises( hass: HomeAssistant, device_registry: dr.DeviceRegistry, client, - caplog: pytest.LogCaptureFixture, domain: str, entry_state: ConfigEntryState, ) -> None: diff --git a/tests/components/webostv/test_diagnostics.py b/tests/components/webostv/test_diagnostics.py index d35dd1fb883..0cf815ce9e2 100644 --- a/tests/components/webostv/test_diagnostics.py +++ b/tests/components/webostv/test_diagnostics.py @@ -1,4 +1,4 @@ -"""Tests for the diagnostics data provided by LG webOS Smart TV.""" +"""Tests for the diagnostics data provided by LG webOS TV.""" from syrupy.assertion import SnapshotAssertion from syrupy.filters import props diff --git a/tests/components/webostv/test_media_player.py b/tests/components/webostv/test_media_player.py index 5789fd19492..d5241dbe668 100644 --- a/tests/components/webostv/test_media_player.py +++ b/tests/components/webostv/test_media_player.py @@ -1,4 +1,4 @@ -"""The tests for the LG webOS media player platform.""" +"""The tests for the LG webOS TV media player platform.""" from datetime import timedelta from http import HTTPStatus @@ -165,7 +165,7 @@ async def test_media_next_previous_track( async def test_select_source_with_empty_source_list( - hass: HomeAssistant, client, caplog: pytest.LogCaptureFixture + hass: HomeAssistant, client ) -> None: """Ensure we don't call client methods when we don't have sources.""" await setup_webostv(hass) @@ -175,11 +175,14 @@ async def test_select_source_with_empty_source_list( ATTR_ENTITY_ID: ENTITY_ID, ATTR_INPUT_SOURCE: "nonexistent", } - await hass.services.async_call(MP_DOMAIN, SERVICE_SELECT_SOURCE, data, True) + with pytest.raises( + HomeAssistantError, + match=f"Source nonexistent not found in the sources list for {TV_NAME}", + ): + await hass.services.async_call(MP_DOMAIN, SERVICE_SELECT_SOURCE, data, True) client.launch_app.assert_not_called() client.set_input.assert_not_called() - assert f"Source nonexistent not found for {TV_NAME}" in caplog.text async def test_select_app_source(hass: HomeAssistant, client) -> None: diff --git a/tests/components/webostv/test_notify.py b/tests/components/webostv/test_notify.py index e57451088e3..fd56f0ea0bb 100644 --- a/tests/components/webostv/test_notify.py +++ b/tests/components/webostv/test_notify.py @@ -1,4 +1,4 @@ -"""The tests for the WebOS TV notify platform.""" +"""The tests for the LG webOS TV notify platform.""" from unittest.mock import call diff --git a/tests/components/webostv/test_trigger.py b/tests/components/webostv/test_trigger.py index d7eeae28ea3..c7decafff73 100644 --- a/tests/components/webostv/test_trigger.py +++ b/tests/components/webostv/test_trigger.py @@ -1,4 +1,4 @@ -"""The tests for WebOS TV automation triggers.""" +"""The tests for LG webOS TV automation triggers.""" from unittest.mock import patch @@ -118,10 +118,10 @@ async def test_webostv_turn_on_trigger_entity_id( assert service_calls[1].data["id"] == 0 -async def test_wrong_trigger_platform_type( +async def test_unknown_trigger_platform_type( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, client ) -> None: - """Test wrong trigger platform type.""" + """Test unknown trigger platform type.""" await setup_webostv(hass) await async_setup_component( @@ -131,7 +131,7 @@ async def test_wrong_trigger_platform_type( automation.DOMAIN: [ { "trigger": { - "platform": "webostv.wrong_type", + "platform": "webostv.unknown", "entity_id": ENTITY_ID, }, "action": { @@ -146,10 +146,7 @@ async def test_wrong_trigger_platform_type( }, ) - assert ( - "ValueError: Unknown webOS Smart TV trigger platform webostv.wrong_type" - in caplog.text - ) + assert "Unknown trigger platform: webostv.unknown" in caplog.text async def test_trigger_invalid_entity_id( @@ -185,7 +182,4 @@ async def test_trigger_invalid_entity_id( }, ) - assert ( - f"ValueError: Entity {invalid_entity} is not a valid webostv entity" - in caplog.text - ) + assert f"Entity {invalid_entity} is not a valid {DOMAIN} entity" in caplog.text