mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 09:47:52 +00:00
Reolink translate key (#140821)
* Add firmware exception translations * Add test * Much nicer syntax * Check if translation key is present in string.json * fix tests * fix typo
This commit is contained in:
parent
07bce8850f
commit
e78a19ae3e
@ -103,6 +103,12 @@
|
|||||||
},
|
},
|
||||||
"config_entry_not_ready": {
|
"config_entry_not_ready": {
|
||||||
"message": "Error while trying to set up {host}: {err}"
|
"message": "Error while trying to set up {host}: {err}"
|
||||||
|
},
|
||||||
|
"update_already_running": {
|
||||||
|
"message": "Reolink firmware update already running, wait on completion before starting another"
|
||||||
|
},
|
||||||
|
"firmware_rate_limit": {
|
||||||
|
"message": "Reolink firmware update server reached hourly rate limit: updating can be tried again in 1 hour"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"issues": {
|
"issues": {
|
||||||
|
@ -31,7 +31,7 @@ from .entity import (
|
|||||||
ReolinkHostCoordinatorEntity,
|
ReolinkHostCoordinatorEntity,
|
||||||
ReolinkHostEntityDescription,
|
ReolinkHostEntityDescription,
|
||||||
)
|
)
|
||||||
from .util import ReolinkConfigEntry, ReolinkData
|
from .util import ReolinkConfigEntry, ReolinkData, raise_translated_error
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
RESUME_AFTER_INSTALL = 15
|
RESUME_AFTER_INSTALL = 15
|
||||||
@ -184,6 +184,7 @@ class ReolinkUpdateBaseEntity(
|
|||||||
f"## Release notes\n\n{new_firmware.release_notes}"
|
f"## Release notes\n\n{new_firmware.release_notes}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@raise_translated_error
|
||||||
async def async_install(
|
async def async_install(
|
||||||
self, version: str | None, backup: bool, **kwargs: Any
|
self, version: str | None, backup: bool, **kwargs: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -196,6 +197,8 @@ class ReolinkUpdateBaseEntity(
|
|||||||
try:
|
try:
|
||||||
await self._host.api.update_firmware(self._channel)
|
await self._host.api.update_firmware(self._channel)
|
||||||
except ReolinkError as err:
|
except ReolinkError as err:
|
||||||
|
if err.translation_key:
|
||||||
|
raise
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="firmware_install_error",
|
translation_key="firmware_install_error",
|
||||||
|
@ -27,6 +27,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
||||||
from homeassistant.helpers import device_registry as dr
|
from homeassistant.helpers import device_registry as dr
|
||||||
from homeassistant.helpers.storage import Store
|
from homeassistant.helpers.storage import Store
|
||||||
|
from homeassistant.helpers.translation import async_get_exception_message
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
@ -97,6 +98,16 @@ def get_device_uid_and_ch(
|
|||||||
return (device_uid, ch, is_chime)
|
return (device_uid, ch, is_chime)
|
||||||
|
|
||||||
|
|
||||||
|
def check_translation_key(err: ReolinkError) -> str | None:
|
||||||
|
"""Check if the translation key from the upstream library is present."""
|
||||||
|
if not err.translation_key:
|
||||||
|
return None
|
||||||
|
if async_get_exception_message(DOMAIN, err.translation_key) == err.translation_key:
|
||||||
|
# translation key not found in strings.json
|
||||||
|
return None
|
||||||
|
return err.translation_key
|
||||||
|
|
||||||
|
|
||||||
# Decorators
|
# Decorators
|
||||||
def raise_translated_error[**P, R](
|
def raise_translated_error[**P, R](
|
||||||
func: Callable[P, Awaitable[R]],
|
func: Callable[P, Awaitable[R]],
|
||||||
@ -110,73 +121,73 @@ def raise_translated_error[**P, R](
|
|||||||
except InvalidParameterError as err:
|
except InvalidParameterError as err:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="invalid_parameter",
|
translation_key=check_translation_key(err) or "invalid_parameter",
|
||||||
translation_placeholders={"err": str(err)},
|
translation_placeholders={"err": str(err)},
|
||||||
) from err
|
) from err
|
||||||
except ApiError as err:
|
except ApiError as err:
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="api_error",
|
translation_key=check_translation_key(err) or "api_error",
|
||||||
translation_placeholders={"err": str(err)},
|
translation_placeholders={"err": str(err)},
|
||||||
) from err
|
) from err
|
||||||
except InvalidContentTypeError as err:
|
except InvalidContentTypeError as err:
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="invalid_content_type",
|
translation_key=check_translation_key(err) or "invalid_content_type",
|
||||||
translation_placeholders={"err": str(err)},
|
translation_placeholders={"err": str(err)},
|
||||||
) from err
|
) from err
|
||||||
except CredentialsInvalidError as err:
|
except CredentialsInvalidError as err:
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="invalid_credentials",
|
translation_key=check_translation_key(err) or "invalid_credentials",
|
||||||
translation_placeholders={"err": str(err)},
|
translation_placeholders={"err": str(err)},
|
||||||
) from err
|
) from err
|
||||||
except LoginError as err:
|
except LoginError as err:
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="login_error",
|
translation_key=check_translation_key(err) or "login_error",
|
||||||
translation_placeholders={"err": str(err)},
|
translation_placeholders={"err": str(err)},
|
||||||
) from err
|
) from err
|
||||||
except NoDataError as err:
|
except NoDataError as err:
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="no_data",
|
translation_key=check_translation_key(err) or "no_data",
|
||||||
translation_placeholders={"err": str(err)},
|
translation_placeholders={"err": str(err)},
|
||||||
) from err
|
) from err
|
||||||
except UnexpectedDataError as err:
|
except UnexpectedDataError as err:
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="unexpected_data",
|
translation_key=check_translation_key(err) or "unexpected_data",
|
||||||
translation_placeholders={"err": str(err)},
|
translation_placeholders={"err": str(err)},
|
||||||
) from err
|
) from err
|
||||||
except NotSupportedError as err:
|
except NotSupportedError as err:
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="not_supported",
|
translation_key=check_translation_key(err) or "not_supported",
|
||||||
translation_placeholders={"err": str(err)},
|
translation_placeholders={"err": str(err)},
|
||||||
) from err
|
) from err
|
||||||
except SubscriptionError as err:
|
except SubscriptionError as err:
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="subscription_error",
|
translation_key=check_translation_key(err) or "subscription_error",
|
||||||
translation_placeholders={"err": str(err)},
|
translation_placeholders={"err": str(err)},
|
||||||
) from err
|
) from err
|
||||||
except ReolinkConnectionError as err:
|
except ReolinkConnectionError as err:
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="connection_error",
|
translation_key=check_translation_key(err) or "connection_error",
|
||||||
translation_placeholders={"err": str(err)},
|
translation_placeholders={"err": str(err)},
|
||||||
) from err
|
) from err
|
||||||
except ReolinkTimeoutError as err:
|
except ReolinkTimeoutError as err:
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="timeout",
|
translation_key=check_translation_key(err) or "timeout",
|
||||||
translation_placeholders={"err": str(err)},
|
translation_placeholders={"err": str(err)},
|
||||||
) from err
|
) from err
|
||||||
except ReolinkError as err:
|
except ReolinkError as err:
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="unexpected",
|
translation_key=check_translation_key(err) or "unexpected",
|
||||||
translation_placeholders={"err": str(err)},
|
translation_placeholders={"err": str(err)},
|
||||||
) from err
|
) from err
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ from unittest.mock import MagicMock, patch
|
|||||||
|
|
||||||
from freezegun.api import FrozenDateTimeFactory
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
import pytest
|
import pytest
|
||||||
from reolink_aio.exceptions import ReolinkError
|
from reolink_aio.exceptions import ApiError, ReolinkError
|
||||||
from reolink_aio.software_version import NewSoftwareVersion
|
from reolink_aio.software_version import NewSoftwareVersion
|
||||||
|
|
||||||
from homeassistant.components.reolink.update import POLL_AFTER_INSTALL, POLL_PROGRESS
|
from homeassistant.components.reolink.update import POLL_AFTER_INSTALL, POLL_PROGRESS
|
||||||
@ -144,6 +144,17 @@ async def test_update_firm(
|
|||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
reolink_connect.update_firmware.side_effect = ApiError(
|
||||||
|
"Test error", translation_key="firmware_rate_limit"
|
||||||
|
)
|
||||||
|
with pytest.raises(HomeAssistantError):
|
||||||
|
await hass.services.async_call(
|
||||||
|
UPDATE_DOMAIN,
|
||||||
|
SERVICE_INSTALL,
|
||||||
|
{ATTR_ENTITY_ID: entity_id},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
# test _async_update_future
|
# test _async_update_future
|
||||||
reolink_connect.camera_sw_version.return_value = "v3.3.0.226_23031644"
|
reolink_connect.camera_sw_version.return_value = "v3.3.0.226_23031644"
|
||||||
reolink_connect.firmware_update_available.return_value = False
|
reolink_connect.firmware_update_available.return_value = False
|
||||||
|
@ -40,6 +40,14 @@ from tests.common import MockConfigEntry
|
|||||||
ApiError("Test error"),
|
ApiError("Test error"),
|
||||||
HomeAssistantError,
|
HomeAssistantError,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
ApiError("Test error", translation_key="firmware_rate_limit"),
|
||||||
|
HomeAssistantError,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ApiError("Test error", translation_key="not_in_strings.json"),
|
||||||
|
HomeAssistantError,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
CredentialsInvalidError("Test error"),
|
CredentialsInvalidError("Test error"),
|
||||||
HomeAssistantError,
|
HomeAssistantError,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user