mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 01:38:02 +00:00
Swallow error 40000 for songpal power on/off (#80563)
* Swallow error 40000 for songpal power on/off * Move ERROR_REQUEST_RETRY to consts * Add tests for the swallow exception behavior * Update tests/components/songpal/test_media_player.py --------- Co-authored-by: Paulus Schoutsen <balloob@gmail.com> Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
parent
81561d4d3e
commit
23c5e60be0
@ -3,3 +3,5 @@ DOMAIN = "songpal"
|
||||
SET_SOUND_SETTING = "set_sound_setting"
|
||||
|
||||
CONF_ENDPOINT = "endpoint"
|
||||
|
||||
ERROR_REQUEST_RETRY = 40000
|
||||
|
@ -34,7 +34,7 @@ from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
from .const import CONF_ENDPOINT, DOMAIN, SET_SOUND_SETTING
|
||||
from .const import CONF_ENDPOINT, DOMAIN, ERROR_REQUEST_RETRY, SET_SOUND_SETTING
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -332,11 +332,27 @@ class SongpalEntity(MediaPlayerEntity):
|
||||
|
||||
async def async_turn_on(self) -> None:
|
||||
"""Turn the device on."""
|
||||
return await self._dev.set_power(True)
|
||||
try:
|
||||
return await self._dev.set_power(True)
|
||||
except SongpalException as ex:
|
||||
if ex.code == ERROR_REQUEST_RETRY:
|
||||
_LOGGER.debug(
|
||||
"Swallowing %s, the device might be already in the wanted state", ex
|
||||
)
|
||||
return
|
||||
raise
|
||||
|
||||
async def async_turn_off(self) -> None:
|
||||
"""Turn the device off."""
|
||||
return await self._dev.set_power(False)
|
||||
try:
|
||||
return await self._dev.set_power(False)
|
||||
except SongpalException as ex:
|
||||
if ex.code == ERROR_REQUEST_RETRY:
|
||||
_LOGGER.debug(
|
||||
"Swallowing %s, the device might be already in the wanted state", ex
|
||||
)
|
||||
return
|
||||
raise
|
||||
|
||||
async def async_mute_volume(self, mute: bool) -> None:
|
||||
"""Mute or unmute the device."""
|
||||
|
@ -14,7 +14,10 @@ from songpal import (
|
||||
|
||||
from homeassistant.components import media_player, songpal
|
||||
from homeassistant.components.media_player import MediaPlayerEntityFeature
|
||||
from homeassistant.components.songpal.const import SET_SOUND_SETTING
|
||||
from homeassistant.components.songpal.const import (
|
||||
ERROR_REQUEST_RETRY,
|
||||
SET_SOUND_SETTING,
|
||||
)
|
||||
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
@ -53,6 +56,15 @@ def _get_attributes(hass):
|
||||
return state.as_dict()["attributes"]
|
||||
|
||||
|
||||
async def _call(hass, service, **argv):
|
||||
await hass.services.async_call(
|
||||
media_player.DOMAIN,
|
||||
service,
|
||||
{"entity_id": ENTITY_ID, **argv},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
||||
async def test_setup_platform(hass: HomeAssistant) -> None:
|
||||
"""Test the legacy setup platform."""
|
||||
mocked_device = _create_mocked_device(throw_exception=True)
|
||||
@ -222,32 +234,24 @@ async def test_services(hass: HomeAssistant) -> None:
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
async def _call(service, **argv):
|
||||
await hass.services.async_call(
|
||||
media_player.DOMAIN,
|
||||
service,
|
||||
{"entity_id": ENTITY_ID, **argv},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
await _call(media_player.SERVICE_TURN_ON)
|
||||
await _call(media_player.SERVICE_TURN_OFF)
|
||||
await _call(media_player.SERVICE_TOGGLE)
|
||||
await _call(hass, media_player.SERVICE_TURN_ON)
|
||||
await _call(hass, media_player.SERVICE_TURN_OFF)
|
||||
await _call(hass, media_player.SERVICE_TOGGLE)
|
||||
assert mocked_device.set_power.call_count == 3
|
||||
mocked_device.set_power.assert_has_calls([call(True), call(False), call(False)])
|
||||
|
||||
await _call(media_player.SERVICE_VOLUME_SET, volume_level=0.6)
|
||||
await _call(media_player.SERVICE_VOLUME_UP)
|
||||
await _call(media_player.SERVICE_VOLUME_DOWN)
|
||||
await _call(hass, media_player.SERVICE_VOLUME_SET, volume_level=0.6)
|
||||
await _call(hass, media_player.SERVICE_VOLUME_UP)
|
||||
await _call(hass, media_player.SERVICE_VOLUME_DOWN)
|
||||
assert mocked_device.volume1.set_volume.call_count == 3
|
||||
mocked_device.volume1.set_volume.assert_has_calls([call(60), call(51), call(49)])
|
||||
|
||||
await _call(media_player.SERVICE_VOLUME_MUTE, is_volume_muted=True)
|
||||
await _call(hass, media_player.SERVICE_VOLUME_MUTE, is_volume_muted=True)
|
||||
mocked_device.volume1.set_mute.assert_called_once_with(True)
|
||||
|
||||
await _call(media_player.SERVICE_SELECT_SOURCE, source="none")
|
||||
await _call(hass, media_player.SERVICE_SELECT_SOURCE, source="none")
|
||||
mocked_device.input1.activate.assert_not_called()
|
||||
await _call(media_player.SERVICE_SELECT_SOURCE, source="title1")
|
||||
await _call(hass, media_player.SERVICE_SELECT_SOURCE, source="title1")
|
||||
mocked_device.input1.activate.assert_called_once()
|
||||
|
||||
await hass.services.async_call(
|
||||
@ -366,3 +370,33 @@ async def test_disconnected(
|
||||
assert warning_records[0].message.endswith("Got disconnected, trying to reconnect")
|
||||
assert warning_records[1].message.endswith("Connection reestablished")
|
||||
assert not any(x.levelno == logging.ERROR for x in caplog.records)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"service", [media_player.SERVICE_TURN_ON, media_player.SERVICE_TURN_OFF]
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("error_code", "swallow"), [(ERROR_REQUEST_RETRY, True), (1234, False)]
|
||||
)
|
||||
async def test_error_swallowing(hass, caplog, service, error_code, swallow):
|
||||
"""Test swallowing specific errors on turn_on and turn_off."""
|
||||
mocked_device = _create_mocked_device()
|
||||
entry = MockConfigEntry(domain=songpal.DOMAIN, data=CONF_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with _patch_media_player_device(mocked_device):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
type(mocked_device).set_power = AsyncMock(
|
||||
side_effect=[
|
||||
SongpalException("Error to swallow", error=(error_code, "Error to swallow"))
|
||||
]
|
||||
)
|
||||
|
||||
if swallow:
|
||||
await _call(hass, service)
|
||||
assert "Swallowing" in caplog.text
|
||||
else:
|
||||
with pytest.raises(SongpalException):
|
||||
await _call(hass, service)
|
||||
|
Loading…
x
Reference in New Issue
Block a user