mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 03:37:07 +00:00
Fix check for locked device in AVM Fritz!SmartHome (#141697)
* feat: raise execption on hvac mode while device is locked * fix: test for setting hvac mode while device is locked. * feat: update translation * feat: add separate translations for HVAC and temperature * fix: test cases * fix: test cases for test_set_preset_mode_boost * rev: code review * rev: exception string * feat: updated error message and added helper function * Update homeassistant/components/fritzbox/strings.json Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com> * fix: translation key * remove check_active_or_lock_mode from async_set_preset_mode --------- Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>
This commit is contained in:
parent
debec3bfbc
commit
aea5760424
@ -144,6 +144,7 @@ class FritzboxThermostat(FritzBoxDeviceEntity, ClimateEntity):
|
||||
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set new target temperature."""
|
||||
self.check_active_or_lock_mode()
|
||||
if kwargs.get(ATTR_HVAC_MODE) is HVACMode.OFF:
|
||||
await self.async_set_hkr_state("off")
|
||||
elif (target_temp := kwargs.get(ATTR_TEMPERATURE)) is not None:
|
||||
@ -168,11 +169,7 @@ class FritzboxThermostat(FritzBoxDeviceEntity, ClimateEntity):
|
||||
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set new operation mode."""
|
||||
if self.data.holiday_active or self.data.summer_active:
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="change_hvac_while_active_mode",
|
||||
)
|
||||
self.check_active_or_lock_mode()
|
||||
if self.hvac_mode is hvac_mode:
|
||||
LOGGER.debug(
|
||||
"%s is already in requested hvac mode %s", self.name, hvac_mode
|
||||
@ -204,11 +201,7 @@ class FritzboxThermostat(FritzBoxDeviceEntity, ClimateEntity):
|
||||
|
||||
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||
"""Set preset mode."""
|
||||
if self.data.holiday_active or self.data.summer_active:
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="change_preset_while_active_mode",
|
||||
)
|
||||
self.check_active_or_lock_mode()
|
||||
await self.async_set_hkr_state(PRESET_API_HKR_STATE_MAPPING[preset_mode])
|
||||
|
||||
@property
|
||||
@ -230,3 +223,17 @@ class FritzboxThermostat(FritzBoxDeviceEntity, ClimateEntity):
|
||||
attrs[ATTR_STATE_WINDOW_OPEN] = self.data.window_open
|
||||
|
||||
return attrs
|
||||
|
||||
def check_active_or_lock_mode(self) -> None:
|
||||
"""Check if in summer/vacation mode or lock enabled."""
|
||||
if self.data.holiday_active or self.data.summer_active:
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="change_settings_while_active_mode",
|
||||
)
|
||||
|
||||
if self.data.lock:
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="change_settings_while_lock_enabled",
|
||||
)
|
||||
|
@ -88,11 +88,11 @@
|
||||
"manual_switching_disabled": {
|
||||
"message": "Can't toggle switch while manual switching is disabled for the device."
|
||||
},
|
||||
"change_preset_while_active_mode": {
|
||||
"message": "Can't change preset while holiday or summer mode is active on the device."
|
||||
"change_settings_while_lock_enabled": {
|
||||
"message": "Can't change settings while manual access for telephone, app, or user interface is disabled on the device"
|
||||
},
|
||||
"change_hvac_while_active_mode": {
|
||||
"message": "Can't change HVAC mode while holiday or summer mode is active on the device."
|
||||
"change_settings_while_active_mode": {
|
||||
"message": "Can't change settings while holiday or summer mode is active on the device."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,6 +211,8 @@ async def test_set_temperature(
|
||||
) -> None:
|
||||
"""Test setting temperature."""
|
||||
device = FritzDeviceClimateMock()
|
||||
device.lock = False
|
||||
|
||||
await setup_config_entry(
|
||||
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
|
||||
)
|
||||
@ -288,6 +290,8 @@ async def test_set_hvac_mode(
|
||||
) -> None:
|
||||
"""Test setting hvac mode."""
|
||||
device = FritzDeviceClimateMock()
|
||||
|
||||
device.lock = False
|
||||
device.target_temperature = target_temperature
|
||||
|
||||
if current_preset is PRESET_COMFORT:
|
||||
@ -335,6 +339,8 @@ async def test_set_preset_mode_comfort(
|
||||
) -> None:
|
||||
"""Test setting preset mode."""
|
||||
device = FritzDeviceClimateMock()
|
||||
|
||||
device.lock = False
|
||||
device.comfort_temperature = comfort_temperature
|
||||
await setup_config_entry(
|
||||
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
|
||||
@ -366,6 +372,8 @@ async def test_set_preset_mode_eco(
|
||||
) -> None:
|
||||
"""Test setting preset mode."""
|
||||
device = FritzDeviceClimateMock()
|
||||
|
||||
device.lock = False
|
||||
device.eco_temperature = eco_temperature
|
||||
await setup_config_entry(
|
||||
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
|
||||
@ -387,6 +395,8 @@ async def test_set_preset_mode_boost(
|
||||
) -> None:
|
||||
"""Test setting preset mode."""
|
||||
device = FritzDeviceClimateMock()
|
||||
device.lock = False
|
||||
|
||||
await setup_config_entry(
|
||||
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
|
||||
)
|
||||
@ -471,11 +481,106 @@ async def test_discover_new_device(hass: HomeAssistant, fritz: Mock) -> None:
|
||||
assert state
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"service_data",
|
||||
[
|
||||
{ATTR_TEMPERATURE: 23},
|
||||
{
|
||||
ATTR_HVAC_MODE: HVACMode.HEAT,
|
||||
ATTR_TEMPERATURE: 25,
|
||||
},
|
||||
],
|
||||
)
|
||||
async def test_set_temperature_lock(
|
||||
hass: HomeAssistant,
|
||||
fritz: Mock,
|
||||
service_data: dict,
|
||||
) -> None:
|
||||
"""Test setting temperature while device is locked."""
|
||||
device = FritzDeviceClimateMock()
|
||||
|
||||
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 change settings while manual access for telephone, app, or user interface is disabled on the device",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: ENTITY_ID, **service_data},
|
||||
True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("service_data", "target_temperature", "current_preset", "expected_call_args"),
|
||||
[
|
||||
# mode off always sets target temperature to 0
|
||||
({ATTR_HVAC_MODE: HVACMode.OFF}, 22, PRESET_COMFORT, [call(0, True)]),
|
||||
({ATTR_HVAC_MODE: HVACMode.OFF}, 16, PRESET_ECO, [call(0, True)]),
|
||||
({ATTR_HVAC_MODE: HVACMode.OFF}, 16, None, [call(0, True)]),
|
||||
# mode heat sets target temperature based on current scheduled preset,
|
||||
# when not already in mode heat
|
||||
({ATTR_HVAC_MODE: HVACMode.HEAT}, 0.0, PRESET_COMFORT, [call(22, True)]),
|
||||
({ATTR_HVAC_MODE: HVACMode.HEAT}, 0.0, PRESET_ECO, [call(16, True)]),
|
||||
({ATTR_HVAC_MODE: HVACMode.HEAT}, 0.0, None, [call(22, True)]),
|
||||
# mode heat does not set target temperature, when already in mode heat
|
||||
({ATTR_HVAC_MODE: HVACMode.HEAT}, 16, PRESET_COMFORT, []),
|
||||
({ATTR_HVAC_MODE: HVACMode.HEAT}, 16, PRESET_ECO, []),
|
||||
({ATTR_HVAC_MODE: HVACMode.HEAT}, 16, None, []),
|
||||
({ATTR_HVAC_MODE: HVACMode.HEAT}, 22, PRESET_COMFORT, []),
|
||||
({ATTR_HVAC_MODE: HVACMode.HEAT}, 22, PRESET_ECO, []),
|
||||
({ATTR_HVAC_MODE: HVACMode.HEAT}, 22, None, []),
|
||||
],
|
||||
)
|
||||
async def test_set_hvac_mode_lock(
|
||||
hass: HomeAssistant,
|
||||
fritz: Mock,
|
||||
service_data: dict,
|
||||
target_temperature: float,
|
||||
current_preset: str,
|
||||
expected_call_args: list[_Call],
|
||||
) -> None:
|
||||
"""Test setting hvac mode while device is locked."""
|
||||
device = FritzDeviceClimateMock()
|
||||
|
||||
device.lock = True
|
||||
device.target_temperature = target_temperature
|
||||
|
||||
if current_preset is PRESET_COMFORT:
|
||||
device.nextchange_temperature = device.eco_temperature
|
||||
elif current_preset is PRESET_ECO:
|
||||
device.nextchange_temperature = device.comfort_temperature
|
||||
else:
|
||||
device.nextchange_endperiod = 0
|
||||
|
||||
assert await setup_config_entry(
|
||||
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
|
||||
)
|
||||
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match="Can't change settings while manual access for telephone, app, or user interface is disabled on the device",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: ENTITY_ID, **service_data},
|
||||
True,
|
||||
)
|
||||
|
||||
|
||||
async def test_holidy_summer_mode(
|
||||
hass: HomeAssistant, freezer: FrozenDateTimeFactory, fritz: Mock
|
||||
) -> None:
|
||||
"""Test holiday and summer mode."""
|
||||
device = FritzDeviceClimateMock()
|
||||
device.lock = False
|
||||
|
||||
await setup_config_entry(
|
||||
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
|
||||
)
|
||||
@ -510,7 +615,7 @@ async def test_holidy_summer_mode(
|
||||
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match="Can't change HVAC mode while holiday or summer mode is active on the device",
|
||||
match="Can't change settings while holiday or summer mode is active on the device",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
"climate",
|
||||
@ -520,7 +625,7 @@ async def test_holidy_summer_mode(
|
||||
)
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match="Can't change preset while holiday or summer mode is active on the device",
|
||||
match="Can't change settings while holiday or summer mode is active on the device",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
"climate",
|
||||
@ -546,7 +651,7 @@ async def test_holidy_summer_mode(
|
||||
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match="Can't change HVAC mode while holiday or summer mode is active on the device",
|
||||
match="Can't change settings while holiday or summer mode is active on the device",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
"climate",
|
||||
@ -556,7 +661,7 @@ async def test_holidy_summer_mode(
|
||||
)
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match="Can't change preset while holiday or summer mode is active on the device",
|
||||
match="Can't change settings while holiday or summer mode is active on the device",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
"climate",
|
||||
|
Loading…
x
Reference in New Issue
Block a user