mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Free color selection for Fritz!Smarthome lights (#66213)
* Fritz light free color selection * Use setcolor as fallback * better debug log message Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com> * change if-clause Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>
This commit is contained in:
parent
1e4690626f
commit
804c888098
@ -3,6 +3,8 @@ from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from requests.exceptions import HTTPError
|
||||
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS,
|
||||
ATTR_COLOR_TEMP,
|
||||
@ -21,6 +23,7 @@ from .const import (
|
||||
COLOR_TEMP_MODE,
|
||||
CONF_COORDINATOR,
|
||||
DOMAIN as FRITZBOX_DOMAIN,
|
||||
LOGGER,
|
||||
)
|
||||
from .coordinator import FritzboxDataUpdateCoordinator
|
||||
|
||||
@ -135,16 +138,33 @@ class FritzboxLight(FritzBoxEntity, LightEntity):
|
||||
level = kwargs[ATTR_BRIGHTNESS]
|
||||
await self.hass.async_add_executor_job(self.device.set_level, level)
|
||||
if kwargs.get(ATTR_HS_COLOR) is not None:
|
||||
hass_hue = int(kwargs[ATTR_HS_COLOR][0])
|
||||
hass_saturation = round(kwargs[ATTR_HS_COLOR][1] * 255.0 / 100.0)
|
||||
# find supported hs values closest to what user selected
|
||||
hue = min(self._supported_hs.keys(), key=lambda x: abs(x - hass_hue))
|
||||
saturation = min(
|
||||
self._supported_hs[hue], key=lambda x: abs(x - hass_saturation)
|
||||
)
|
||||
await self.hass.async_add_executor_job(
|
||||
self.device.set_color, (hue, saturation)
|
||||
)
|
||||
# Try setunmappedcolor first. This allows free color selection,
|
||||
# but we don't know if its supported by all devices.
|
||||
try:
|
||||
# HA gives 0..360 for hue, fritz light only supports 0..359
|
||||
unmapped_hue = int(kwargs[ATTR_HS_COLOR][0] % 360)
|
||||
unmapped_saturation = round(kwargs[ATTR_HS_COLOR][1] * 255.0 / 100.0)
|
||||
await self.hass.async_add_executor_job(
|
||||
self.device.set_unmapped_color, (unmapped_hue, unmapped_saturation)
|
||||
)
|
||||
# This will raise 400 BAD REQUEST if the setunmappedcolor is not available
|
||||
except HTTPError as err:
|
||||
if err.response.status_code != 400:
|
||||
raise
|
||||
LOGGER.debug(
|
||||
"fritzbox does not support method 'setunmappedcolor', fallback to 'setcolor'"
|
||||
)
|
||||
# find supported hs values closest to what user selected
|
||||
hue = min(
|
||||
self._supported_hs.keys(), key=lambda x: abs(x - unmapped_hue)
|
||||
)
|
||||
saturation = min(
|
||||
self._supported_hs[hue],
|
||||
key=lambda x: abs(x - unmapped_saturation),
|
||||
)
|
||||
await self.hass.async_add_executor_job(
|
||||
self.device.set_color, (hue, saturation)
|
||||
)
|
||||
|
||||
if kwargs.get(ATTR_COLOR_TEMP) is not None:
|
||||
kelvin = color.color_temperature_kelvin_to_mired(kwargs[ATTR_COLOR_TEMP])
|
||||
|
@ -113,7 +113,34 @@ async def test_turn_on_color(hass: HomeAssistant, fritz: Mock):
|
||||
assert await setup_config_entry(
|
||||
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
|
||||
)
|
||||
assert await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_BRIGHTNESS: 100, ATTR_HS_COLOR: (100, 70)},
|
||||
True,
|
||||
)
|
||||
assert device.set_state_on.call_count == 1
|
||||
assert device.set_level.call_count == 1
|
||||
assert device.set_unmapped_color.call_count == 1
|
||||
|
||||
|
||||
async def test_turn_on_color_unsupported_api_method(hass: HomeAssistant, fritz: Mock):
|
||||
"""Test turn device on in mapped color mode if unmapped is not supported."""
|
||||
device = FritzDeviceLightMock()
|
||||
device.get_color_temps.return_value = [2700, 6500]
|
||||
device.get_colors.return_value = {
|
||||
"Red": [("100", "70", "10"), ("100", "50", "10"), ("100", "30", "10")]
|
||||
}
|
||||
mockresponse = Mock()
|
||||
mockresponse.status_code = 400
|
||||
|
||||
error = HTTPError("Bad Request")
|
||||
error.response = mockresponse
|
||||
device.set_unmapped_color.side_effect = error
|
||||
|
||||
assert await setup_config_entry(
|
||||
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
|
||||
)
|
||||
assert await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
@ -135,7 +162,6 @@ async def test_turn_off(hass: HomeAssistant, fritz: Mock):
|
||||
assert await setup_config_entry(
|
||||
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
|
||||
)
|
||||
|
||||
assert await hass.services.async_call(
|
||||
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user