Bump pytradfri to 8.0.1 and fix fan preset mode "Auto" bug (#63920)
* Move util functions * Fix errors * Revert changes * Fix tests * Use self.async_set_percentage() * Fix calculation functions and associated tests * Handle case of 0 * Update tests/components/tradfri/test_util.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Update tests/components/tradfri/test_util.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Update tests/components/tradfri/test_util.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Handle case of 0 * Update homeassistant/components/tradfri/fan.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>pull/64098/head
parent
a978661545
commit
b52a8ba37a
|
@ -36,3 +36,4 @@ PLATFORMS = [
|
|||
Platform.SWITCH,
|
||||
]
|
||||
TIMEOUT_API = 30
|
||||
ATTR_MAX_FAN_STEPS = 49
|
||||
|
|
|
@ -17,7 +17,24 @@ from homeassistant.core import HomeAssistant
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .base_class import TradfriBaseDevice
|
||||
from .const import ATTR_AUTO, CONF_GATEWAY_ID, DEVICES, DOMAIN, KEY_API
|
||||
from .const import (
|
||||
ATTR_AUTO,
|
||||
ATTR_MAX_FAN_STEPS,
|
||||
CONF_GATEWAY_ID,
|
||||
DEVICES,
|
||||
DOMAIN,
|
||||
KEY_API,
|
||||
)
|
||||
|
||||
|
||||
def _from_fan_percentage(percentage: int) -> int:
|
||||
"""Convert percent to a value that the Tradfri API understands."""
|
||||
return round(max(2, (percentage / 100 * ATTR_MAX_FAN_STEPS) + 1))
|
||||
|
||||
|
||||
def _from_fan_speed(fan_speed: int) -> int:
|
||||
"""Convert the Tradfri API fan speed to a percentage value."""
|
||||
return max(round((fan_speed - 1) / ATTR_MAX_FAN_STEPS * 100), 0)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
|
@ -38,23 +55,6 @@ async def async_setup_entry(
|
|||
)
|
||||
|
||||
|
||||
def _from_percentage(percentage: int) -> int:
|
||||
"""Convert percent to a value that the Tradfri API understands."""
|
||||
if percentage < 20:
|
||||
# The device cannot be set to speed 5 (10%), so we should turn off the device
|
||||
# for any value below 20
|
||||
return 0
|
||||
|
||||
nearest_10: int = round(percentage / 10) * 10 # Round to nearest multiple of 10
|
||||
return round(nearest_10 / 100 * 50)
|
||||
|
||||
|
||||
def _from_fan_speed(fan_speed: int) -> int:
|
||||
"""Convert the Tradfri API fan speed to a percentage value."""
|
||||
nearest_10: int = round(fan_speed / 10) * 10 # Round to nearest multiple of 10
|
||||
return round(nearest_10 / 50 * 100)
|
||||
|
||||
|
||||
class TradfriAirPurifierFan(TradfriBaseDevice, FanEntity):
|
||||
"""The platform class required by Home Assistant."""
|
||||
|
||||
|
@ -80,24 +80,19 @@ class TradfriAirPurifierFan(TradfriBaseDevice, FanEntity):
|
|||
|
||||
These are the steps:
|
||||
0 = Off
|
||||
10 = Min
|
||||
15
|
||||
20
|
||||
25
|
||||
30
|
||||
35
|
||||
40
|
||||
45
|
||||
1 = Preset: Auto mode
|
||||
2 = Min
|
||||
... with step size 1
|
||||
50 = Max
|
||||
"""
|
||||
return 10
|
||||
return ATTR_MAX_FAN_STEPS
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if switch is on."""
|
||||
if not self._device_data:
|
||||
return False
|
||||
return cast(bool, self._device_data.mode)
|
||||
return cast(bool, self._device_data.state)
|
||||
|
||||
@property
|
||||
def preset_modes(self) -> list[str] | None:
|
||||
|
@ -121,7 +116,7 @@ class TradfriAirPurifierFan(TradfriBaseDevice, FanEntity):
|
|||
if not self._device_data:
|
||||
return None
|
||||
|
||||
if self._device_data.mode == ATTR_AUTO:
|
||||
if self._device_data.is_auto_mode:
|
||||
return ATTR_AUTO
|
||||
|
||||
return None
|
||||
|
@ -133,7 +128,8 @@ class TradfriAirPurifierFan(TradfriBaseDevice, FanEntity):
|
|||
|
||||
if not preset_mode == ATTR_AUTO:
|
||||
raise ValueError("Preset must be 'Auto'.")
|
||||
await self._api(self._device_control.set_mode(1))
|
||||
|
||||
await self._api(self._device_control.turn_on_auto_mode())
|
||||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
|
@ -147,7 +143,7 @@ class TradfriAirPurifierFan(TradfriBaseDevice, FanEntity):
|
|||
return
|
||||
|
||||
if percentage is not None:
|
||||
await self._api(self._device_control.set_mode(_from_percentage(percentage)))
|
||||
await self.async_set_percentage(percentage)
|
||||
return
|
||||
|
||||
preset_mode = preset_mode or ATTR_AUTO
|
||||
|
@ -158,13 +154,19 @@ class TradfriAirPurifierFan(TradfriBaseDevice, FanEntity):
|
|||
if not self._device_control:
|
||||
return
|
||||
|
||||
await self._api(self._device_control.set_mode(_from_percentage(percentage)))
|
||||
if percentage == 0:
|
||||
await self.async_turn_off()
|
||||
return
|
||||
|
||||
await self._api(
|
||||
self._device_control.set_fan_speed(_from_fan_percentage(percentage))
|
||||
)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off the fan."""
|
||||
if not self._device_control:
|
||||
return
|
||||
await self._api(self._device_control.set_mode(0))
|
||||
await self._api(self._device_control.turn_off())
|
||||
|
||||
def _refresh(self, device: Command, write_ha: bool = True) -> None:
|
||||
"""Refresh the purifier data."""
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "IKEA TR\u00c5DFRI",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/tradfri",
|
||||
"requirements": ["pytradfri[async]==7.2.1"],
|
||||
"requirements": ["pytradfri[async]==8.0.1"],
|
||||
"homekit": {
|
||||
"models": ["TRADFRI"]
|
||||
},
|
||||
|
|
|
@ -2005,7 +2005,7 @@ pytouchline==0.7
|
|||
pytraccar==0.10.0
|
||||
|
||||
# homeassistant.components.tradfri
|
||||
pytradfri[async]==7.2.1
|
||||
pytradfri[async]==8.0.1
|
||||
|
||||
# homeassistant.components.trafikverket_train
|
||||
# homeassistant.components.trafikverket_weatherstation
|
||||
|
|
|
@ -1230,7 +1230,7 @@ pytile==2021.12.0
|
|||
pytraccar==0.10.0
|
||||
|
||||
# homeassistant.components.tradfri
|
||||
pytradfri[async]==7.2.1
|
||||
pytradfri[async]==8.0.1
|
||||
|
||||
# homeassistant.components.trafikverket_train
|
||||
# homeassistant.components.trafikverket_weatherstation
|
||||
|
|
|
@ -1,22 +1,31 @@
|
|||
"""Tradfri utility function tests."""
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.tradfri.fan import _from_fan_speed, _from_percentage
|
||||
from homeassistant.components.tradfri.fan import _from_fan_percentage, _from_fan_speed
|
||||
|
||||
|
||||
def test_from_fan_speed():
|
||||
@pytest.mark.parametrize(
|
||||
"fan_speed, expected_result",
|
||||
[
|
||||
(0, 0),
|
||||
(2, 2),
|
||||
(25, 49),
|
||||
(50, 100),
|
||||
],
|
||||
)
|
||||
def test_from_fan_speed(fan_speed, expected_result):
|
||||
"""Test that we can convert fan speed to percentage value."""
|
||||
assert _from_fan_speed(41) == 80
|
||||
assert _from_fan_speed(fan_speed) == expected_result
|
||||
|
||||
|
||||
def test_from_percentage():
|
||||
@pytest.mark.parametrize(
|
||||
"percentage, expected_result",
|
||||
[
|
||||
(1, 2),
|
||||
(100, 50),
|
||||
(50, 26),
|
||||
],
|
||||
)
|
||||
def test_from_percentage(percentage, expected_result):
|
||||
"""Test that we can convert percentage value to fan speed."""
|
||||
assert _from_percentage(84) == 40
|
||||
|
||||
|
||||
def test_from_percentage_limit():
|
||||
"""
|
||||
Test that we can convert percentage value to fan speed.
|
||||
|
||||
Handle special case of percent value being below 20.
|
||||
"""
|
||||
assert _from_percentage(10) == 0
|
||||
assert _from_fan_percentage(percentage) == expected_result
|
||||
|
|
Loading…
Reference in New Issue