diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index 5855dbfe1c2..e41ffc75964 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -779,7 +779,7 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): entity_description: LightEntityDescription _attr_brightness: int | None = None - _attr_color_mode: ColorMode = ColorMode.UNKNOWN + _attr_color_mode: ColorMode | None = None _attr_color_temp_kelvin: int | None = None _attr_effect_list: list[str] | None = None _attr_effect: str | None = None @@ -801,7 +801,7 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): return self._attr_brightness @cached_property - def color_mode(self) -> ColorMode: + def color_mode(self) -> ColorMode | None: """Return the color mode of the light.""" return self._attr_color_mode @@ -1014,6 +1014,10 @@ class LightEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): _is_on = self.is_on color_mode = self.color_mode if _is_on else None + if _is_on and color_mode is None: + raise HomeAssistantError( + f"{self.entity_id} ({type(self)}) does not report a color mode" + ) effect: str | None = None if LightEntityFeature.EFFECT in supported_features: diff --git a/homeassistant/components/mqtt/light/schema_template.py b/homeassistant/components/mqtt/light/schema_template.py index 3eaeb89caa5..13b83f082b0 100644 --- a/homeassistant/components/mqtt/light/schema_template.py +++ b/homeassistant/components/mqtt/light/schema_template.py @@ -187,6 +187,7 @@ class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity): color_modes.add(ColorMode.HS) self._attr_supported_color_modes = filter_supported_color_modes(color_modes) self._fixed_color_mode = None + self._attr_color_mode = ColorMode.UNKNOWN if self.supported_color_modes and len(self.supported_color_modes) == 1: self._fixed_color_mode = next(iter(self.supported_color_modes)) self._attr_color_mode = self._fixed_color_mode diff --git a/homeassistant/components/openrgb/light.py b/homeassistant/components/openrgb/light.py index c599ab6c3ed..ce4e47c6fa7 100644 --- a/homeassistant/components/openrgb/light.py +++ b/homeassistant/components/openrgb/light.py @@ -158,7 +158,7 @@ class OpenRGBLight(CoordinatorEntity[OpenRGBCoordinator], LightEntity): else: mode_supports_colors = check_if_mode_supports_color(mode_data) - color_mode = ColorMode.UNKNOWN + color_mode = None rgb_color = None brightness = None on_by_color = True @@ -194,7 +194,7 @@ class OpenRGBLight(CoordinatorEntity[OpenRGBCoordinator], LightEntity): # If Off by color, retain previous color mode to avoid changing the UI color_mode = self._attr_color_mode - if color_mode == ColorMode.UNKNOWN: + if color_mode is None: # If color mode is still unknown, default to RGB color_mode = ColorMode.RGB diff --git a/pylint/plugins/hass_enforce_type_hints.py b/pylint/plugins/hass_enforce_type_hints.py index 1b920d8c55d..47416da20cc 100644 --- a/pylint/plugins/hass_enforce_type_hints.py +++ b/pylint/plugins/hass_enforce_type_hints.py @@ -1837,7 +1837,7 @@ _INHERITANCE_MATCH: dict[str, list[ClassTypeHintMatch]] = { ), TypeHintMatch( function_name="color_mode", - return_type=["ColorMode"], + return_type=["ColorMode", None], mandatory=True, ), TypeHintMatch( diff --git a/tests/components/light/test_init.py b/tests/components/light/test_init.py index 1b06c152867..ad8a88d5d97 100644 --- a/tests/components/light/test_init.py +++ b/tests/components/light/test_init.py @@ -2353,6 +2353,40 @@ def test_filter_supported_color_modes() -> None: assert light.filter_supported_color_modes(supported) == {light.ColorMode.BRIGHTNESS} +@pytest.mark.parametrize( + ("color_mode", "supported_color_modes", "error_expected"), + [ + (None, {light.ColorMode.ONOFF}, True), + (light.ColorMode.ONOFF, {light.ColorMode.ONOFF}, False), + ], +) +async def test_report_no_color_mode( + hass: HomeAssistant, + caplog: pytest.LogCaptureFixture, + color_mode: str, + supported_color_modes: set[str], + error_expected: bool, +) -> None: + """Test a light setting no color mode.""" + + class MockLightEntityEntity(light.LightEntity): + _attr_color_mode = color_mode + _attr_is_on = True + _attr_supported_features = light.LightEntityFeature.EFFECT + _attr_supported_color_modes = supported_color_modes + + entity = MockLightEntityEntity() + platform = MockEntityPlatform(hass, domain="test", platform_name="test") + await platform.async_add_entities([entity]) + raised_error = "" + try: + entity._async_calculate_state() + except HomeAssistantError as err: + raised_error = str(err) + expected_error = "does not report a color mode" + assert (expected_error in raised_error) is error_expected + + @pytest.mark.parametrize( ("color_mode", "supported_color_modes", "warning_expected"), [