Deprecate None effect instead of breaking it for Hue (#142073)

* Deprecate effect none instead of breaking it for Hue

* add guard for unknown effect value

* revert guard

* Fix

* Add test

* Add test

* Add test

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
This commit is contained in:
Marcel van der Veldt 2025-04-02 15:39:31 +02:00 committed by GitHub
parent 4c44d2f4d9
commit 0871bf13a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 69 additions and 2 deletions

View File

@ -197,5 +197,11 @@
}
}
}
},
"issues": {
"deprecated_effect_none": {
"title": "Light turned on with deprecated effect",
"description": "A light was turned on with the deprecated effect `None`. This has been replaced with `off`. Please update any automations, scenes, or scripts that use this effect."
}
}
}

View File

@ -29,6 +29,7 @@ from homeassistant.components.light import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.util import color as color_util
from ..bridge import HueBridge
@ -44,6 +45,9 @@ FALLBACK_MIN_KELVIN = 6500
FALLBACK_MAX_KELVIN = 2000
FALLBACK_KELVIN = 5800 # halfway
# HA 2025.4 replaced the deprecated effect "None" with HA default "off"
DEPRECATED_EFFECT_NONE = "None"
async def async_setup_entry(
hass: HomeAssistant,
@ -233,6 +237,23 @@ class HueLight(HueBaseEntity, LightEntity):
self._color_temp_active = color_temp is not None
flash = kwargs.get(ATTR_FLASH)
effect = effect_str = kwargs.get(ATTR_EFFECT)
if effect_str == DEPRECATED_EFFECT_NONE:
# deprecated effect "None" is now "off"
effect_str = EFFECT_OFF
async_create_issue(
self.hass,
DOMAIN,
"deprecated_effect_none",
breaks_in_ha_version="2025.10.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key="deprecated_effect_none",
)
self.logger.warning(
"Detected deprecated effect 'None' in %s, use 'off' instead. "
"This will stop working in HA 2025.10",
self.entity_id,
)
if effect_str == EFFECT_OFF:
# ignore effect if set to "off" and we have no effect active
# the special effect "off" is only used to stop an active effect

View File

@ -2,9 +2,14 @@
from unittest.mock import Mock
from homeassistant.components.light import ColorMode
from homeassistant.components.light import (
ATTR_EFFECT,
DOMAIN as LIGHT_DOMAIN,
ColorMode,
)
from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_ON
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers import entity_registry as er, issue_registry as ir
from homeassistant.util.json import JsonArrayType
from .conftest import setup_platform
@ -639,3 +644,38 @@ async def test_grouped_lights(
mock_bridge_v2.mock_requests[index]["json"]["identify"]["action"]
== "identify"
)
async def test_light_turn_on_service_deprecation(
hass: HomeAssistant,
mock_bridge_v2: Mock,
v2_resources_test_data: JsonArrayType,
issue_registry: ir.IssueRegistry,
) -> None:
"""Test calling the turn on service on a light."""
await mock_bridge_v2.api.load_test_data(v2_resources_test_data)
test_light_id = "light.hue_light_with_color_temperature_only"
await setup_platform(hass, mock_bridge_v2, "light")
event = {
"id": "3a6710fa-4474-4eba-b533-5e6e72968feb",
"type": "light",
"effects": {"status": "candle"},
}
mock_bridge_v2.api.emit_event("update", event)
await hass.async_block_till_done()
# test disable effect
# it should send a request with effect set to "no_effect"
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: test_light_id,
ATTR_EFFECT: "None",
},
blocking=True,
)
assert mock_bridge_v2.mock_requests[0]["json"]["effects"]["effect"] == "no_effect"