Raise on failed switching in devolo Home Network (#143072)

This commit is contained in:
Guido Schmitz 2025-04-16 13:49:37 +02:00 committed by GitHub
parent fbba0d9a21
commit 8de23b9559
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 69 additions and 68 deletions

View File

@ -114,9 +114,14 @@ class DevoloSwitchEntity[_DataT: _DataType](
translation_key="password_protected", translation_key="password_protected",
translation_placeholders={"title": self.entry.title}, translation_placeholders={"title": self.entry.title},
) from ex ) from ex
except DeviceUnavailable: except DeviceUnavailable as ex:
pass # The coordinator will handle this raise HomeAssistantError(
await self.coordinator.async_request_refresh() translation_domain=DOMAIN,
translation_key="no_response",
translation_placeholders={"title": self.entry.title},
) from ex
finally:
await self.coordinator.async_request_refresh()
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the entity off.""" """Turn the entity off."""
@ -129,6 +134,11 @@ class DevoloSwitchEntity[_DataT: _DataType](
translation_key="password_protected", translation_key="password_protected",
translation_placeholders={"title": self.entry.title}, translation_placeholders={"title": self.entry.title},
) from ex ) from ex
except DeviceUnavailable: except DeviceUnavailable as ex:
pass # The coordinator will handle this raise HomeAssistantError(
await self.coordinator.async_request_refresh() translation_domain=DOMAIN,
translation_key="no_response",
translation_placeholders={"title": self.entry.title},
) from ex
finally:
await self.coordinator.async_request_refresh()

View File

@ -64,6 +64,7 @@ class MockDevice(Device):
return_value=FIRMWARE_UPDATE_AVAILABLE return_value=FIRMWARE_UPDATE_AVAILABLE
) )
self.device.async_get_led_setting = AsyncMock(return_value=False) self.device.async_get_led_setting = AsyncMock(return_value=False)
self.device.async_set_led_setting = AsyncMock(return_value=True)
self.device.async_restart = AsyncMock(return_value=True) self.device.async_restart = AsyncMock(return_value=True)
self.device.async_uptime = AsyncMock(return_value=UPTIME) self.device.async_uptime = AsyncMock(return_value=UPTIME)
self.device.async_start_wps = AsyncMock(return_value=True) self.device.async_start_wps = AsyncMock(return_value=True)
@ -71,6 +72,7 @@ class MockDevice(Device):
return_value=CONNECTED_STATIONS return_value=CONNECTED_STATIONS
) )
self.device.async_get_wifi_guest_access = AsyncMock(return_value=GUEST_WIFI) self.device.async_get_wifi_guest_access = AsyncMock(return_value=GUEST_WIFI)
self.device.async_set_wifi_guest_access = AsyncMock(return_value=True)
self.device.async_get_wifi_neighbor_access_points = AsyncMock( self.device.async_get_wifi_neighbor_access_points = AsyncMock(
return_value=NEIGHBOR_ACCESS_POINTS return_value=NEIGHBOR_ACCESS_POINTS
) )

View File

@ -1,7 +1,7 @@
"""Tests for the devolo Home Network switch.""" """Tests for the devolo Home Network switch."""
from datetime import timedelta from datetime import timedelta
from unittest.mock import AsyncMock, patch from unittest.mock import AsyncMock
from devolo_plc_api.device_api import WifiGuestAccessGet from devolo_plc_api.device_api import WifiGuestAccessGet
from devolo_plc_api.exceptions.device import DevicePasswordProtected, DeviceUnavailable from devolo_plc_api.exceptions.device import DevicePasswordProtected, DeviceUnavailable
@ -16,6 +16,7 @@ from homeassistant.components.devolo_home_network.const import (
from homeassistant.components.switch import DOMAIN as PLATFORM from homeassistant.components.switch import DOMAIN as PLATFORM
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_TURN_OFF, SERVICE_TURN_OFF,
SERVICE_TURN_ON, SERVICE_TURN_ON,
STATE_OFF, STATE_OFF,
@ -106,18 +107,15 @@ async def test_update_enable_guest_wifi(
mock_device.device.async_get_wifi_guest_access.return_value = WifiGuestAccessGet( mock_device.device.async_get_wifi_guest_access.return_value = WifiGuestAccessGet(
enabled=False enabled=False
) )
with patch( await hass.services.async_call(
"devolo_plc_api.device_api.deviceapi.DeviceApi.async_set_wifi_guest_access", PLATFORM, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: state_key}, blocking=True
new=AsyncMock(), )
) as turn_off:
await hass.services.async_call(
PLATFORM, SERVICE_TURN_OFF, {"entity_id": state_key}, blocking=True
)
state = hass.states.get(state_key) state = hass.states.get(state_key)
assert state is not None assert state is not None
assert state.state == STATE_OFF assert state.state == STATE_OFF
turn_off.assert_called_once_with(False) mock_device.device.async_set_wifi_guest_access.assert_called_once_with(False)
mock_device.device.async_set_wifi_guest_access.reset_mock()
freezer.tick(REQUEST_REFRESH_DEFAULT_COOLDOWN) freezer.tick(REQUEST_REFRESH_DEFAULT_COOLDOWN)
async_fire_time_changed(hass) async_fire_time_changed(hass)
@ -127,18 +125,15 @@ async def test_update_enable_guest_wifi(
mock_device.device.async_get_wifi_guest_access.return_value = WifiGuestAccessGet( mock_device.device.async_get_wifi_guest_access.return_value = WifiGuestAccessGet(
enabled=True enabled=True
) )
with patch( await hass.services.async_call(
"devolo_plc_api.device_api.deviceapi.DeviceApi.async_set_wifi_guest_access", PLATFORM, SERVICE_TURN_ON, {ATTR_ENTITY_ID: state_key}, blocking=True
new=AsyncMock(), )
) as turn_on:
await hass.services.async_call(
PLATFORM, SERVICE_TURN_ON, {"entity_id": state_key}, blocking=True
)
state = hass.states.get(state_key) state = hass.states.get(state_key)
assert state is not None assert state is not None
assert state.state == STATE_ON assert state.state == STATE_ON
turn_on.assert_called_once_with(True) mock_device.device.async_set_wifi_guest_access.assert_called_once_with(True)
mock_device.device.async_set_wifi_guest_access.reset_mock()
freezer.tick(REQUEST_REFRESH_DEFAULT_COOLDOWN) freezer.tick(REQUEST_REFRESH_DEFAULT_COOLDOWN)
async_fire_time_changed(hass) async_fire_time_changed(hass)
@ -146,17 +141,17 @@ async def test_update_enable_guest_wifi(
# Device unavailable # Device unavailable
mock_device.device.async_get_wifi_guest_access.side_effect = DeviceUnavailable() mock_device.device.async_get_wifi_guest_access.side_effect = DeviceUnavailable()
with patch( mock_device.device.async_set_wifi_guest_access.side_effect = DeviceUnavailable()
"devolo_plc_api.device_api.deviceapi.DeviceApi.async_set_wifi_guest_access",
side_effect=DeviceUnavailable, with pytest.raises(
HomeAssistantError, match=f"Device {entry.title} did not respond"
): ):
await hass.services.async_call( await hass.services.async_call(
PLATFORM, SERVICE_TURN_ON, {"entity_id": state_key}, blocking=True PLATFORM, SERVICE_TURN_ON, {ATTR_ENTITY_ID: state_key}, blocking=True
) )
state = hass.states.get(state_key)
state = hass.states.get(state_key) assert state is not None
assert state is not None assert state.state == STATE_UNAVAILABLE
assert state.state == STATE_UNAVAILABLE
await hass.config_entries.async_unload(entry.entry_id) await hass.config_entries.async_unload(entry.entry_id)
@ -191,18 +186,15 @@ async def test_update_enable_leds(
# Switch off # Switch off
mock_device.device.async_get_led_setting.return_value = False mock_device.device.async_get_led_setting.return_value = False
with patch( await hass.services.async_call(
"devolo_plc_api.device_api.deviceapi.DeviceApi.async_set_led_setting", PLATFORM, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: state_key}, blocking=True
new=AsyncMock(), )
) as turn_off:
await hass.services.async_call(
PLATFORM, SERVICE_TURN_OFF, {"entity_id": state_key}, blocking=True
)
state = hass.states.get(state_key) state = hass.states.get(state_key)
assert state is not None assert state is not None
assert state.state == STATE_OFF assert state.state == STATE_OFF
turn_off.assert_called_once_with(False) mock_device.device.async_set_led_setting.assert_called_once_with(False)
mock_device.device.async_set_led_setting.reset_mock()
freezer.tick(REQUEST_REFRESH_DEFAULT_COOLDOWN) freezer.tick(REQUEST_REFRESH_DEFAULT_COOLDOWN)
async_fire_time_changed(hass) async_fire_time_changed(hass)
@ -210,18 +202,15 @@ async def test_update_enable_leds(
# Switch on # Switch on
mock_device.device.async_get_led_setting.return_value = True mock_device.device.async_get_led_setting.return_value = True
with patch( await hass.services.async_call(
"devolo_plc_api.device_api.deviceapi.DeviceApi.async_set_led_setting", PLATFORM, SERVICE_TURN_ON, {ATTR_ENTITY_ID: state_key}, blocking=True
new=AsyncMock(), )
) as turn_on:
await hass.services.async_call(
PLATFORM, SERVICE_TURN_ON, {"entity_id": state_key}, blocking=True
)
state = hass.states.get(state_key) state = hass.states.get(state_key)
assert state is not None assert state is not None
assert state.state == STATE_ON assert state.state == STATE_ON
turn_on.assert_called_once_with(True) mock_device.device.async_set_led_setting.assert_called_once_with(True)
mock_device.device.async_set_led_setting.reset_mock()
freezer.tick(REQUEST_REFRESH_DEFAULT_COOLDOWN) freezer.tick(REQUEST_REFRESH_DEFAULT_COOLDOWN)
async_fire_time_changed(hass) async_fire_time_changed(hass)
@ -229,17 +218,17 @@ async def test_update_enable_leds(
# Device unavailable # Device unavailable
mock_device.device.async_get_led_setting.side_effect = DeviceUnavailable() mock_device.device.async_get_led_setting.side_effect = DeviceUnavailable()
with patch( mock_device.device.async_set_led_setting.side_effect = DeviceUnavailable()
"devolo_plc_api.device_api.deviceapi.DeviceApi.async_set_led_setting",
side_effect=DeviceUnavailable, with pytest.raises(
HomeAssistantError, match=f"Device {entry.title} did not respond"
): ):
await hass.services.async_call( await hass.services.async_call(
PLATFORM, SERVICE_TURN_OFF, {"entity_id": state_key}, blocking=True PLATFORM, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: state_key}, blocking=True
) )
state = hass.states.get(state_key)
state = hass.states.get(state_key) assert state is not None
assert state is not None assert state.state == STATE_UNAVAILABLE
assert state.state == STATE_UNAVAILABLE
await hass.config_entries.async_unload(entry.entry_id) await hass.config_entries.async_unload(entry.entry_id)
@ -308,7 +297,7 @@ async def test_auth_failed(
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
await hass.services.async_call( await hass.services.async_call(
PLATFORM, SERVICE_TURN_ON, {"entity_id": state_key}, blocking=True PLATFORM, SERVICE_TURN_ON, {ATTR_ENTITY_ID: state_key}, blocking=True
) )
await hass.async_block_till_done() await hass.async_block_till_done()