Update Fritz! lights to use kelvin (#79733)

This commit is contained in:
Lars 2022-10-25 13:45:02 +02:00 committed by GitHub
parent 36bb0bbc1a
commit 1c8156bd33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 22 deletions

View File

@ -7,7 +7,7 @@ from requests.exceptions import HTTPError
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP, ATTR_COLOR_TEMP_KELVIN,
ATTR_HS_COLOR, ATTR_HS_COLOR,
ColorMode, ColorMode,
LightEntity, LightEntity,
@ -15,7 +15,6 @@ from homeassistant.components.light import (
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util import color
from . import FritzBoxEntity from . import FritzBoxEntity
from .const import ( from .const import (
@ -67,17 +66,13 @@ class FritzboxLight(FritzBoxEntity, LightEntity):
coordinator: FritzboxDataUpdateCoordinator, coordinator: FritzboxDataUpdateCoordinator,
ain: str, ain: str,
supported_colors: dict, supported_colors: dict,
supported_color_temps: list[str], supported_color_temps: list[int],
) -> None: ) -> None:
"""Initialize the FritzboxLight entity.""" """Initialize the FritzboxLight entity."""
super().__init__(coordinator, ain, None) super().__init__(coordinator, ain, None)
max_kelvin = int(max(supported_color_temps)) self._attr_max_color_temp_kelvin = int(max(supported_color_temps))
min_kelvin = int(min(supported_color_temps)) self._attr_min_color_temp_kelvin = int(min(supported_color_temps))
# max kelvin is min mireds and min kelvin is max mireds
self._attr_min_mireds = color.color_temperature_kelvin_to_mired(max_kelvin)
self._attr_max_mireds = color.color_temperature_kelvin_to_mired(min_kelvin)
# Fritz!DECT 500 only supports 12 values for hue, with 3 saturations each. # Fritz!DECT 500 only supports 12 values for hue, with 3 saturations each.
# Map supported colors to dict {hue: [sat1, sat2, sat3]} for easier lookup # Map supported colors to dict {hue: [sat1, sat2, sat3]} for easier lookup
@ -112,13 +107,12 @@ class FritzboxLight(FritzBoxEntity, LightEntity):
return (hue, float(saturation) * 100.0 / 255.0) return (hue, float(saturation) * 100.0 / 255.0)
@property @property
def color_temp(self) -> int | None: def color_temp_kelvin(self) -> int | None:
"""Return the CT color value.""" """Return the CT color value."""
if self.device.color_mode != COLOR_TEMP_MODE: if self.device.color_mode != COLOR_TEMP_MODE:
return None return None
kelvin = self.device.color_temp return self.device.color_temp # type: ignore [no-any-return]
return color.color_temperature_kelvin_to_mired(kelvin)
@property @property
def color_mode(self) -> ColorMode: def color_mode(self) -> ColorMode:
@ -166,9 +160,10 @@ class FritzboxLight(FritzBoxEntity, LightEntity):
self.device.set_color, (hue, saturation) self.device.set_color, (hue, saturation)
) )
if kwargs.get(ATTR_COLOR_TEMP) is not None: if kwargs.get(ATTR_COLOR_TEMP_KELVIN) is not None:
kelvin = color.color_temperature_kelvin_to_mired(kwargs[ATTR_COLOR_TEMP]) await self.hass.async_add_executor_job(
await self.hass.async_add_executor_job(self.device.set_color_temp, kelvin) self.device.set_color_temp, kwargs[ATTR_COLOR_TEMP_KELVIN]
)
await self.hass.async_add_executor_job(self.device.set_state_on) await self.hass.async_add_executor_job(self.device.set_state_on)
await self.coordinator.async_refresh() await self.coordinator.async_refresh()

View File

@ -1,6 +1,6 @@
"""Tests for AVM Fritz!Box light component.""" """Tests for AVM Fritz!Box light component."""
from datetime import timedelta from datetime import timedelta
from unittest.mock import Mock from unittest.mock import Mock, call
from requests.exceptions import HTTPError from requests.exceptions import HTTPError
@ -11,8 +11,10 @@ from homeassistant.components.fritzbox.const import (
) )
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP, ATTR_COLOR_TEMP_KELVIN,
ATTR_HS_COLOR, ATTR_HS_COLOR,
ATTR_MAX_COLOR_TEMP_KELVIN,
ATTR_MIN_COLOR_TEMP_KELVIN,
DOMAIN, DOMAIN,
) )
from homeassistant.const import ( from homeassistant.const import (
@ -24,7 +26,6 @@ from homeassistant.const import (
STATE_ON, STATE_ON,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.util import color
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from . import FritzDeviceLightMock, setup_config_entry from . import FritzDeviceLightMock, setup_config_entry
@ -53,9 +54,9 @@ async def test_setup(hass: HomeAssistant, fritz: Mock):
assert state assert state
assert state.state == STATE_ON assert state.state == STATE_ON
assert state.attributes[ATTR_FRIENDLY_NAME] == "fake_name" assert state.attributes[ATTR_FRIENDLY_NAME] == "fake_name"
assert state.attributes[ATTR_COLOR_TEMP] == color.color_temperature_kelvin_to_mired( assert state.attributes[ATTR_COLOR_TEMP_KELVIN] == 2700
2700 assert state.attributes[ATTR_MIN_COLOR_TEMP_KELVIN] == 2700
) assert state.attributes[ATTR_MAX_COLOR_TEMP_KELVIN] == 6500
async def test_setup_color(hass: HomeAssistant, fritz: Mock): async def test_setup_color(hass: HomeAssistant, fritz: Mock):
@ -95,12 +96,14 @@ async def test_turn_on(hass: HomeAssistant, fritz: Mock):
assert await hass.services.async_call( assert await hass.services.async_call(
DOMAIN, DOMAIN,
SERVICE_TURN_ON, SERVICE_TURN_ON,
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_BRIGHTNESS: 100, ATTR_COLOR_TEMP: 300}, {ATTR_ENTITY_ID: ENTITY_ID, ATTR_BRIGHTNESS: 100, ATTR_COLOR_TEMP_KELVIN: 3000},
True, True,
) )
assert device.set_state_on.call_count == 1 assert device.set_state_on.call_count == 1
assert device.set_level.call_count == 1 assert device.set_level.call_count == 1
assert device.set_color_temp.call_count == 1 assert device.set_color_temp.call_count == 1
assert device.set_color_temp.call_args_list == [call(3000)]
assert device.set_level.call_args_list == [call(100)]
async def test_turn_on_color(hass: HomeAssistant, fritz: Mock): async def test_turn_on_color(hass: HomeAssistant, fritz: Mock):
@ -122,6 +125,10 @@ async def test_turn_on_color(hass: HomeAssistant, fritz: Mock):
assert device.set_state_on.call_count == 1 assert device.set_state_on.call_count == 1
assert device.set_level.call_count == 1 assert device.set_level.call_count == 1
assert device.set_unmapped_color.call_count == 1 assert device.set_unmapped_color.call_count == 1
assert device.set_level.call_args_list == [call(100)]
assert device.set_unmapped_color.call_args_list == [
call((100, round(70 * 255.0 / 100.0)))
]
async def test_turn_on_color_unsupported_api_method(hass: HomeAssistant, fritz: Mock): async def test_turn_on_color_unsupported_api_method(hass: HomeAssistant, fritz: Mock):
@ -150,6 +157,8 @@ async def test_turn_on_color_unsupported_api_method(hass: HomeAssistant, fritz:
assert device.set_state_on.call_count == 1 assert device.set_state_on.call_count == 1
assert device.set_level.call_count == 1 assert device.set_level.call_count == 1
assert device.set_color.call_count == 1 assert device.set_color.call_count == 1
assert device.set_level.call_args_list == [call(100)]
assert device.set_color.call_args_list == [call((100, 70))]
async def test_turn_off(hass: HomeAssistant, fritz: Mock): async def test_turn_off(hass: HomeAssistant, fritz: Mock):