Check for fullcolorsupport in fritzbox light (#136850)

This commit is contained in:
Lars 2025-01-29 17:15:54 +01:00 committed by GitHub
parent b2ec72d75f
commit fa6df1cc25
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 34 deletions

View File

@ -4,8 +4,6 @@ from __future__ import annotations
from typing import Any, cast
from requests.exceptions import HTTPError
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP_KELVIN,
@ -124,27 +122,22 @@ class FritzboxLight(FritzBoxDeviceEntity, LightEntity):
level = kwargs[ATTR_BRIGHTNESS]
await self.hass.async_add_executor_job(self.data.set_level, level, True)
if kwargs.get(ATTR_HS_COLOR) is not None:
# 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(
cast(float, kwargs[ATTR_HS_COLOR][1]) * 255.0 / 100.0
)
# HA gives 0..360 for hue, fritz light only supports 0..359
unmapped_hue = int(kwargs[ATTR_HS_COLOR][0] % 360)
unmapped_saturation = round(
cast(float, kwargs[ATTR_HS_COLOR][1]) * 255.0 / 100.0
)
if self.data.fullcolorsupport:
LOGGER.debug("device has fullcolorsupport, using 'setunmappedcolor'")
await self.hass.async_add_executor_job(
self.data.set_unmapped_color,
(unmapped_hue, unmapped_saturation),
0,
True,
)
# This will raise 400 BAD REQUEST if the setunmappedcolor is not available
except HTTPError as err:
if err.response.status_code != 400:
raise
else:
LOGGER.debug(
"fritzbox does not support method 'setunmappedcolor', fallback to"
" 'setcolor'"
"device has no fullcolorsupport, using supported colors with 'setcolor'"
)
# find supported hs values closest to what user selected
hue = min(

View File

@ -3,7 +3,6 @@
from datetime import timedelta
from unittest.mock import Mock, call
import pytest
from requests.exceptions import HTTPError
from homeassistant.components.fritzbox.const import (
@ -166,6 +165,7 @@ async def test_turn_on_color(hass: HomeAssistant, fritz: Mock) -> None:
device.get_colors.return_value = {
"Red": [("100", "70", "10"), ("100", "50", "10"), ("100", "30", "10")]
}
device.fullcolorsupport = True
assert await setup_config_entry(
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
)
@ -178,13 +178,14 @@ async def test_turn_on_color(hass: HomeAssistant, fritz: Mock) -> None:
assert device.set_state_on.call_count == 1
assert device.set_level.call_count == 1
assert device.set_unmapped_color.call_count == 1
assert device.set_color.call_count == 0
assert device.set_level.call_args_list == [call(100, True)]
assert device.set_unmapped_color.call_args_list == [
call((100, round(70 * 255.0 / 100.0)), 0, True)
]
async def test_turn_on_color_unsupported_api_method(
async def test_turn_on_color_no_fullcolorsupport(
hass: HomeAssistant, fritz: Mock
) -> None:
"""Test turn device on in mapped color mode if unmapped is not supported."""
@ -193,16 +194,11 @@ async def test_turn_on_color_unsupported_api_method(
device.get_colors.return_value = {
"Red": [("100", "70", "10"), ("100", "50", "10"), ("100", "30", "10")]
}
device.fullcolorsupport = False
assert await setup_config_entry(
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
)
# test fallback to `setcolor`
error = HTTPError("Bad Request")
error.response = Mock()
error.response.status_code = 400
device.set_unmapped_color.side_effect = error
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
@ -212,19 +208,10 @@ async def test_turn_on_color_unsupported_api_method(
assert device.set_state_on.call_count == 1
assert device.set_level.call_count == 1
assert device.set_color.call_count == 1
assert device.set_unmapped_color.call_count == 0
assert device.set_level.call_args_list == [call(100, True)]
assert device.set_color.call_args_list == [call((100, 70), 0, True)]
# test for unknown error
error.response.status_code = 500
with pytest.raises(HTTPError, match="Bad Request"):
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_BRIGHTNESS: 100, ATTR_HS_COLOR: (100, 70)},
True,
)
async def test_turn_off(hass: HomeAssistant, fritz: Mock) -> None:
"""Test turn device off."""