mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-12 06:44:04 +02:00
Adopt has_entity_name to fix duplicated entity ids on HA 2026.4+ (#1499)
* Adopt has_entity_name to fix duplicated entity ids on HA 2026.4+
Since HA core 2026.4 (PR 166246) composes entity names as device name +
entity name, and only strips the device prefix when the entity name
starts with it. Adaptive Lighting's names ('Adaptive Lighting Sleep
Mode: stairs' on device 'Adaptive Lighting: stairs') never match, so
new installs get ids like
switch.adaptive_lighting_stairs_adaptive_lighting_sleep_mode_stairs.
Adopt has_entity_name: the main switch takes the device name
('Adaptive Lighting: <name>'), the simple switches use their role
('Sleep Mode', 'Adapt Brightness', 'Adapt Color'). Unique ids are
unchanged, so existing installs keep their entity ids via the registry.
Fixes #1459
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Test the new entity ids and that existing ones survive
The renamed constants were defined but never asserted, so neither the
fresh-install ids nor the registry-preservation claim were covered.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test: keep the apply-service test light on
Avoid generating brightness zero in the attribute-change helper, which turns the light off and makes the test depend on the current adaptive brightness.
---------
Co-authored-by: proscar87 <proscar87@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Bas Nijholt <bas@nijho.lt>
Co-authored-by: Bas Nijholt <basnijholt@gmail.com>
This commit is contained in:
parent
67d4a2f657
commit
55f871fd0c
2 changed files with 46 additions and 9 deletions
|
|
@ -852,6 +852,8 @@ def _attributes_have_changed(
|
|||
class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
||||
"""Representation of a Adaptive Lighting switch."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
|
|
@ -1003,9 +1005,10 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
def name(self) -> str | None:
|
||||
"""Return the name of the device if any."""
|
||||
return f"Adaptive Lighting: {self._name}"
|
||||
# The main switch takes the device name "Adaptive Lighting: <name>"
|
||||
return None
|
||||
|
||||
@property
|
||||
def unique_id(self) -> str:
|
||||
|
|
@ -1024,7 +1027,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
identifiers={
|
||||
(DOMAIN, self._name),
|
||||
},
|
||||
name=self._name,
|
||||
name=f"Adaptive Lighting: {self._name}",
|
||||
entry_type=DeviceEntryType.SERVICE,
|
||||
)
|
||||
|
||||
|
|
@ -1636,6 +1639,8 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
class SimpleSwitch(SwitchEntity, RestoreEntity):
|
||||
"""Representation of a Adaptive Lighting switch."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
which: str,
|
||||
|
|
@ -1657,8 +1662,8 @@ class SimpleSwitch(SwitchEntity, RestoreEntity):
|
|||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Return the name of the device if any."""
|
||||
return self._name
|
||||
"""Return the name of the entity within its device."""
|
||||
return self._which
|
||||
|
||||
@property
|
||||
def unique_id(self) -> str:
|
||||
|
|
|
|||
|
|
@ -155,9 +155,9 @@ ENTITY_LIGHT_2 = "light.light_2"
|
|||
ENTITY_LIGHT_3 = "light.light_3"
|
||||
_SWITCH_FMT = f"{SWITCH_DOMAIN}.{DOMAIN}"
|
||||
ENTITY_SWITCH = f"{_SWITCH_FMT}_{DEFAULT_NAME}"
|
||||
ENTITY_SLEEP_MODE_SWITCH = f"{_SWITCH_FMT}_sleep_mode_{DEFAULT_NAME}"
|
||||
ENTITY_ADAPT_BRIGHTNESS_SWITCH = f"{_SWITCH_FMT}_adapt_brightness_{DEFAULT_NAME}"
|
||||
ENTITY_ADAPT_COLOR_SWITCH = f"{_SWITCH_FMT}_adapt_color_{DEFAULT_NAME}"
|
||||
ENTITY_SLEEP_MODE_SWITCH = f"{_SWITCH_FMT}_{DEFAULT_NAME}_sleep_mode"
|
||||
ENTITY_ADAPT_BRIGHTNESS_SWITCH = f"{_SWITCH_FMT}_{DEFAULT_NAME}_adapt_brightness"
|
||||
ENTITY_ADAPT_COLOR_SWITCH = f"{_SWITCH_FMT}_{DEFAULT_NAME}_adapt_color"
|
||||
|
||||
ORIG_TIMEZONE = dt_util.DEFAULT_TIME_ZONE
|
||||
|
||||
|
|
@ -1092,7 +1092,7 @@ async def test_apply_service(hass):
|
|||
assert entity_id not in switch.lights
|
||||
|
||||
def increased_brightness():
|
||||
return (light._attr_brightness + 100) % 255
|
||||
return max(1, (light._attr_brightness + 100) % 255)
|
||||
|
||||
def increased_color_temp():
|
||||
return max(
|
||||
|
|
@ -3254,6 +3254,38 @@ async def test_detect_non_ha_changes_with_separate_turn_on_commands(hass):
|
|||
), f"AL overrode manual brightness {manual_brightness} with {al_brightness}"
|
||||
|
||||
|
||||
async def test_fresh_install_entity_ids(hass):
|
||||
"""Test the entity ids a new install gets with device-relative naming."""
|
||||
_, switch = await setup_switch(hass, {})
|
||||
|
||||
assert switch.entity_id == ENTITY_SWITCH
|
||||
assert switch.sleep_mode_switch.entity_id == ENTITY_SLEEP_MODE_SWITCH
|
||||
assert switch.adapt_brightness_switch.entity_id == ENTITY_ADAPT_BRIGHTNESS_SWITCH
|
||||
assert switch.adapt_color_switch.entity_id == ENTITY_ADAPT_COLOR_SWITCH
|
||||
|
||||
|
||||
async def test_existing_entity_ids_are_preserved(hass):
|
||||
"""Test an install predating this change keeps its entity ids.
|
||||
|
||||
The unique ids are unchanged, so the entity registry must keep the
|
||||
classic `..._sleep_mode_<name>` id instead of renaming the entity.
|
||||
"""
|
||||
classic_entity_id = f"{_SWITCH_FMT}_sleep_mode_{DEFAULT_NAME}"
|
||||
assert classic_entity_id != ENTITY_SLEEP_MODE_SWITCH
|
||||
|
||||
registry = entity_registry.async_get(hass)
|
||||
registry.async_get_or_create(
|
||||
SWITCH_DOMAIN,
|
||||
DOMAIN,
|
||||
f"{DEFAULT_NAME}_sleep_mode",
|
||||
suggested_object_id=classic_entity_id.split(".", 1)[1],
|
||||
)
|
||||
|
||||
_, switch = await setup_switch(hass, {})
|
||||
|
||||
assert switch.sleep_mode_switch.entity_id == classic_entity_id
|
||||
|
||||
|
||||
def test_validate_ui_options_win_over_stale_data():
|
||||
"""A UI-configured entry's `options` (from the options flow) must win.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue