mirror of
https://github.com/home-assistant/core
synced 2024-07-21 10:44:07 +00:00
Don't allow switch toggle when device in locked in AVM FRITZ!SmartHome (#120132)
* fix: set state of the FritzBox-Switch to disabled if the option for manuel switching in the userinterface is disabled * feat: raise an error instead of disabling switch * feat: rename method signature * fix: tests * fix: wrong import * feat: Update homeassistant/components/fritzbox/strings.json Update error message Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com> * Update tests/components/fritzbox/test_switch.py feat: update test Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com> * make ruff happy * fix expected error message check --------- Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>
This commit is contained in:
parent
dd6cc82f70
commit
9b2915efed
|
@ -81,6 +81,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exceptions": {
|
"exceptions": {
|
||||||
|
"manual_switching_disabled": {
|
||||||
|
"message": "Can't toggle switch while manual switching is disabled for the device."
|
||||||
|
},
|
||||||
"change_preset_while_active_mode": {
|
"change_preset_while_active_mode": {
|
||||||
"message": "Can't change preset while holiday or summer mode is active on the device."
|
"message": "Can't change preset while holiday or summer mode is active on the device."
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,9 +6,11 @@ from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.switch import SwitchEntity
|
from homeassistant.components.switch import SwitchEntity
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import FritzBoxDeviceEntity
|
from . import FritzBoxDeviceEntity
|
||||||
|
from .const import DOMAIN
|
||||||
from .coordinator import FritzboxConfigEntry
|
from .coordinator import FritzboxConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,10 +50,20 @@ class FritzboxSwitch(FritzBoxDeviceEntity, SwitchEntity):
|
||||||
|
|
||||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||||
"""Turn the switch on."""
|
"""Turn the switch on."""
|
||||||
|
self.check_lock_state()
|
||||||
await self.hass.async_add_executor_job(self.data.set_switch_state_on)
|
await self.hass.async_add_executor_job(self.data.set_switch_state_on)
|
||||||
await self.coordinator.async_refresh()
|
await self.coordinator.async_refresh()
|
||||||
|
|
||||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Turn the switch off."""
|
"""Turn the switch off."""
|
||||||
|
self.check_lock_state()
|
||||||
await self.hass.async_add_executor_job(self.data.set_switch_state_off)
|
await self.hass.async_add_executor_job(self.data.set_switch_state_off)
|
||||||
await self.coordinator.async_refresh()
|
await self.coordinator.async_refresh()
|
||||||
|
|
||||||
|
def check_lock_state(self) -> None:
|
||||||
|
"""Raise an Error if manual switching via FRITZ!Box user interface is disabled."""
|
||||||
|
if self.data.lock:
|
||||||
|
raise HomeAssistantError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="manual_switching_disabled",
|
||||||
|
)
|
||||||
|
|
|
@ -151,7 +151,7 @@ class FritzDeviceSwitchMock(FritzEntityBaseMock):
|
||||||
has_thermostat = False
|
has_thermostat = False
|
||||||
has_blind = False
|
has_blind = False
|
||||||
switch_state = "fake_state"
|
switch_state = "fake_state"
|
||||||
lock = "fake_locked"
|
lock = False
|
||||||
power = 5678
|
power = 5678
|
||||||
present = True
|
present = True
|
||||||
temperature = 1.23
|
temperature = 1.23
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
|
|
||||||
|
import pytest
|
||||||
from requests.exceptions import HTTPError
|
from requests.exceptions import HTTPError
|
||||||
|
|
||||||
from homeassistant.components.fritzbox.const import DOMAIN as FB_DOMAIN
|
from homeassistant.components.fritzbox.const import DOMAIN as FB_DOMAIN
|
||||||
|
@ -29,6 +30,7 @@ from homeassistant.const import (
|
||||||
UnitOfTemperature,
|
UnitOfTemperature,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
|
@ -130,6 +132,7 @@ async def test_turn_on(hass: HomeAssistant, fritz: Mock) -> None:
|
||||||
async def test_turn_off(hass: HomeAssistant, fritz: Mock) -> None:
|
async def test_turn_off(hass: HomeAssistant, fritz: Mock) -> None:
|
||||||
"""Test turn device off."""
|
"""Test turn device off."""
|
||||||
device = FritzDeviceSwitchMock()
|
device = FritzDeviceSwitchMock()
|
||||||
|
|
||||||
assert await setup_config_entry(
|
assert await setup_config_entry(
|
||||||
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
|
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
|
||||||
)
|
)
|
||||||
|
@ -137,9 +140,36 @@ async def test_turn_off(hass: HomeAssistant, fritz: Mock) -> None:
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
||||||
)
|
)
|
||||||
|
|
||||||
assert device.set_switch_state_off.call_count == 1
|
assert device.set_switch_state_off.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_toggle_while_locked(hass: HomeAssistant, fritz: Mock) -> None:
|
||||||
|
"""Test toggling while device is locked."""
|
||||||
|
device = FritzDeviceSwitchMock()
|
||||||
|
device.lock = True
|
||||||
|
|
||||||
|
assert await setup_config_entry(
|
||||||
|
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(
|
||||||
|
HomeAssistantError,
|
||||||
|
match="Can't toggle switch while manual switching is disabled for the device",
|
||||||
|
):
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(
|
||||||
|
HomeAssistantError,
|
||||||
|
match="Can't toggle switch while manual switching is disabled for the device",
|
||||||
|
):
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_update(hass: HomeAssistant, fritz: Mock) -> None:
|
async def test_update(hass: HomeAssistant, fritz: Mock) -> None:
|
||||||
"""Test update without error."""
|
"""Test update without error."""
|
||||||
device = FritzDeviceSwitchMock()
|
device = FritzDeviceSwitchMock()
|
||||||
|
|
Loading…
Reference in a new issue