diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index 8bfacb09924..10463172700 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -952,8 +952,8 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): def __validate_color_mode( self, - color_mode: ColorMode | str | None, - supported_color_modes: set[ColorMode] | set[str], + color_mode: ColorMode | None, + supported_color_modes: set[ColorMode], effect: str | None, ) -> None: """Validate the color mode.""" @@ -966,23 +966,10 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): # color modes if color_mode in supported_color_modes: return - # Warning added in 2024.3, reject in 2025.3 - if not self.__color_mode_reported and self.__should_report_light_issue(): - self.__color_mode_reported = True - report_issue = self._suggest_report_issue() - _LOGGER.warning( - ( - "%s (%s) set to unsupported color mode %s, expected one of %s, " - "this will stop working in Home Assistant Core 2025.3, " - "please %s" - ), - self.entity_id, - type(self), - color_mode, - supported_color_modes, - report_issue, - ) - return + raise HomeAssistantError( + f"{self.entity_id} ({type(self)}) set to unsupported color mode " + f"{color_mode}, expected one of {supported_color_modes}" + ) # When an effect is active, the color mode should indicate what adjustments are # supported by the effect. To make this possible, we allow the light to set its @@ -995,23 +982,11 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): if color_mode in effect_color_modes: return - # Warning added in 2024.3, reject in 2025.3 - if not self.__color_mode_reported and self.__should_report_light_issue(): - self.__color_mode_reported = True - report_issue = self._suggest_report_issue() - _LOGGER.warning( - ( - "%s (%s) set to unsupported color mode %s when rendering an effect," - " expected one of %s, this will stop working in Home Assistant " - "Core 2025.3, please %s" - ), - self.entity_id, - type(self), - color_mode, - effect_color_modes, - report_issue, - ) - return + raise HomeAssistantError( + f"{self.entity_id} ({type(self)}) set to unsupported color mode " + f"{color_mode} when rendering an effect, expected one " + f"of {effect_color_modes}" + ) def __validate_supported_color_modes( self, @@ -1053,11 +1028,11 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): _is_on = self.is_on color_mode = self.color_mode if _is_on else None - effect: str | None + effect: str | None = None if LightEntityFeature.EFFECT in supported_features: - data[ATTR_EFFECT] = effect = self.effect if _is_on else None - else: - effect = None + if _is_on: + effect = self.effect + data[ATTR_EFFECT] = effect self.__validate_color_mode(color_mode, legacy_supported_color_modes, effect) diff --git a/tests/components/light/test_init.py b/tests/components/light/test_init.py index bb145a426c2..08f6021d851 100644 --- a/tests/components/light/test_init.py +++ b/tests/components/light/test_init.py @@ -129,7 +129,9 @@ async def test_services( ent1, ent2, ent3 = mock_light_entities ent1.supported_color_modes = [light.ColorMode.HS] + ent1.color_mode = light.ColorMode.HS ent3.supported_color_modes = [light.ColorMode.HS] + ent3.color_mode = light.ColorMode.HS ent1.supported_features = light.LightEntityFeature.TRANSITION ent2.supported_features = ( light.LightEntityFeature.EFFECT | light.LightEntityFeature.TRANSITION @@ -539,6 +541,7 @@ async def test_light_profiles( ent1, _, _ = mock_light_entities ent1.supported_color_modes = [light.ColorMode.HS] + ent1.color_mode = light.ColorMode.HS ent1.supported_features = light.LightEntityFeature.TRANSITION await hass.services.async_call( @@ -1140,6 +1143,7 @@ async def test_light_service_call_rgbw(hass: HomeAssistant) -> None: """Test rgbw functionality in service calls.""" entity0 = MockLight("Test_rgbw", STATE_ON) entity0.supported_color_modes = {light.ColorMode.RGBW} + entity0.color_mode = light.ColorMode.RGBW setup_test_component_platform(hass, light.DOMAIN, [entity0]) @@ -1309,12 +1313,15 @@ async def test_light_service_call_color_conversion(hass: HomeAssistant) -> None: entity0 = entities[0] entity0.supported_color_modes = {light.ColorMode.HS} + entity0.color_mode = light.ColorMode.HS entity1 = entities[1] entity1.supported_color_modes = {light.ColorMode.RGB} + entity1.color_mode = light.ColorMode.RGB entity2 = entities[2] entity2.supported_color_modes = {light.ColorMode.XY} + entity2.color_mode = light.ColorMode.XY entity3 = entities[3] entity3.supported_color_modes = { @@ -1322,15 +1329,19 @@ async def test_light_service_call_color_conversion(hass: HomeAssistant) -> None: light.ColorMode.RGB, light.ColorMode.XY, } + entity3.color_mode = light.ColorMode.HS entity4 = entities[4] entity4.supported_color_modes = {light.ColorMode.RGBW} + entity4.color_mode = light.ColorMode.RGBW entity5 = entities[5] entity5.supported_color_modes = {light.ColorMode.RGBWW} + entity5.color_mode = light.ColorMode.RGBWW entity6 = entities[6] entity6.supported_color_modes = {light.ColorMode.COLOR_TEMP} + entity6.color_mode = light.ColorMode.COLOR_TEMP assert await async_setup_component(hass, "light", {"light": {"platform": "test"}}) await hass.async_block_till_done() @@ -1778,12 +1789,15 @@ async def test_light_service_call_color_temp_emulation(hass: HomeAssistant) -> N entity0 = entities[0] entity0.supported_color_modes = {light.ColorMode.COLOR_TEMP, light.ColorMode.HS} + entity0.color_mode = light.ColorMode.COLOR_TEMP entity1 = entities[1] entity1.supported_color_modes = {light.ColorMode.HS} + entity1.color_mode = light.ColorMode.HS entity2 = entities[2] entity2.supported_color_modes = {light.ColorMode.HS, light.ColorMode.WHITE} + entity2.color_mode = light.ColorMode.HS assert await async_setup_component(hass, "light", {"light": {"platform": "test"}}) await hass.async_block_till_done() @@ -1838,9 +1852,11 @@ async def test_light_service_call_color_temp_conversion(hass: HomeAssistant) -> light.ColorMode.COLOR_TEMP, light.ColorMode.RGBWW, } + entity0.color_mode = light.ColorMode.COLOR_TEMP entity1 = entities[1] entity1.supported_color_modes = {light.ColorMode.RGBWW} + entity1.color_mode = light.ColorMode.RGBWW assert entity1.min_color_temp_kelvin == 2000 assert entity1.max_color_temp_kelvin == 6535 @@ -1956,6 +1972,7 @@ async def test_light_service_call_white_mode(hass: HomeAssistant) -> None: """Test color_mode white in service calls.""" entity0 = MockLight("Test_white", STATE_ON) entity0.supported_color_modes = {light.ColorMode.HS, light.ColorMode.WHITE} + entity0.color_mode = light.ColorMode.HS setup_test_component_platform(hass, light.DOMAIN, [entity0]) assert await async_setup_component(hass, "light", {"light": {"platform": "test"}}) @@ -2367,7 +2384,7 @@ async def test_report_no_color_modes( @pytest.mark.parametrize( - ("color_mode", "supported_color_modes", "effect", "warning_expected"), + ("color_mode", "supported_color_modes", "effect", "error_expected"), [ (light.ColorMode.ONOFF, {light.ColorMode.ONOFF}, None, False), # A light which supports brightness should not set its color mode to on_off @@ -2397,7 +2414,7 @@ async def test_report_invalid_color_mode( color_mode: str, supported_color_modes: set[str], effect: str | None, - warning_expected: bool, + error_expected: bool, ) -> None: """Test a light setting an invalid color mode.""" @@ -2411,9 +2428,13 @@ async def test_report_invalid_color_mode( entity = MockLightEntityEntity() platform = MockEntityPlatform(hass, domain="test", platform_name="test") await platform.async_add_entities([entity]) - entity._async_calculate_state() - expected_warning = f"set to unsupported color mode {color_mode}" - assert (expected_warning in caplog.text) is warning_expected + raised_error = "" + try: + entity._async_calculate_state() + except HomeAssistantError as err: + raised_error = str(err) + expected_error = f"set to unsupported color mode {color_mode}" + assert (expected_error in raised_error) is error_expected @pytest.mark.parametrize(