Raise HomeAssistantError from tplink light effect service (#135081)

pull/135109/head
Steven B. 2025-01-08 14:12:21 +00:00 committed by GitHub
parent 63eb27df7b
commit 6f6d485530
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 111 additions and 3 deletions

View File

@ -6,7 +6,7 @@ from collections.abc import Sequence
import logging
from typing import Any
from kasa import Device, DeviceType, LightState, Module
from kasa import Device, DeviceType, KasaException, LightState, Module
from kasa.interfaces import Light, LightEffect
from kasa.iot import IotDevice
import voluptuous as vol
@ -24,12 +24,14 @@ from homeassistant.components.light import (
filter_supported_color_modes,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_platform
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import VolDictType
from . import TPLinkConfigEntry, legacy_device_id
from .const import DOMAIN
from .coordinator import TPLinkDataUpdateCoordinator
from .entity import CoordinatedTPLinkEntity, async_refresh_after
@ -462,7 +464,17 @@ class TPLinkLightEffectEntity(TPLinkLightEntity):
if transition_range:
effect["transition_range"] = transition_range
effect["transition"] = 0
await self._effect_module.set_custom_effect(effect)
try:
await self._effect_module.set_custom_effect(effect)
except KasaException as ex:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="set_custom_effect",
translation_placeholders={
"effect": str(effect),
"exc": str(ex),
},
) from ex
async def async_set_sequence_effect(
self,
@ -484,4 +496,14 @@ class TPLinkLightEffectEntity(TPLinkLightEntity):
"spread": spread,
"direction": direction,
}
await self._effect_module.set_custom_effect(effect)
try:
await self._effect_module.set_custom_effect(effect)
except KasaException as ex:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="set_custom_effect",
translation_placeholders={
"effect": str(effect),
"exc": str(ex),
},
) from ex

View File

@ -394,6 +394,9 @@
},
"device_authentication": {
"message": "Device authentication error {func}: {exc}"
},
"set_custom_effect": {
"message": "Error trying to set custom effect {effect}: {exc}"
}
},
"issues": {

View File

@ -3,6 +3,7 @@
from __future__ import annotations
from datetime import timedelta
import re
from unittest.mock import MagicMock, PropertyMock
from freezegun.api import FrozenDateTimeFactory
@ -36,6 +37,10 @@ from homeassistant.components.light import (
EFFECT_OFF,
)
from homeassistant.components.tplink.const import DOMAIN
from homeassistant.components.tplink.light import (
SERVICE_RANDOM_EFFECT,
SERVICE_SEQUENCE_EFFECT,
)
from homeassistant.config_entries import SOURCE_REAUTH
from homeassistant.const import (
ATTR_ENTITY_ID,
@ -839,6 +844,84 @@ async def test_smart_strip_custom_random_effect(hass: HomeAssistant) -> None:
light_effect.set_custom_effect.reset_mock()
@pytest.mark.parametrize(
("service_name", "service_params", "expected_extra_params"),
[
pytest.param(
SERVICE_SEQUENCE_EFFECT,
{
"sequence": [[340, 20, 50], [20, 50, 50], [0, 100, 50]],
},
{
"type": "sequence",
"sequence": [(340, 20, 50), (20, 50, 50), (0, 100, 50)],
"repeat_times": 0,
"spread": 1,
"direction": 4,
},
id="sequence",
),
pytest.param(
SERVICE_RANDOM_EFFECT,
{"init_states": [340, 20, 50]},
{"type": "random", "init_states": [[340, 20, 50]], "random_seed": 100},
id="random",
),
],
)
async def test_smart_strip_effect_service_error(
hass: HomeAssistant,
service_name: str,
service_params: dict,
expected_extra_params: dict,
) -> None:
"""Test smart strip custom random effects."""
already_migrated_config_entry = MockConfigEntry(
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=MAC_ADDRESS
)
already_migrated_config_entry.add_to_hass(hass)
device = _mocked_device(
modules=[Module.Light, Module.LightEffect], alias="my_light"
)
light_effect = device.modules[Module.LightEffect]
with _patch_discovery(device=device), _patch_connect(device=device):
await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}})
await hass.async_block_till_done()
entity_id = "light.my_light"
state = hass.states.get(entity_id)
assert state.state == STATE_ON
light_effect.set_custom_effect.side_effect = KasaException("failed")
base = {
"custom": 1,
"id": "yMwcNpLxijmoKamskHCvvravpbnIqAIN",
"brightness": 100,
"name": "Custom",
"segments": [0],
"expansion_strategy": 1,
"enable": 1,
"duration": 0,
"transition": 0,
}
expected_params = {**base, **expected_extra_params}
expected_msg = f"Error trying to set custom effect {expected_params}: failed"
with pytest.raises(HomeAssistantError, match=re.escape(expected_msg)):
await hass.services.async_call(
DOMAIN,
service_name,
{
ATTR_ENTITY_ID: entity_id,
**service_params,
},
blocking=True,
)
async def test_smart_strip_custom_random_effect_at_start(hass: HomeAssistant) -> None:
"""Test smart strip custom random effects at startup."""
already_migrated_config_entry = MockConfigEntry(