Fix WLED entity naming for multi-segment setups#169670
Fix WLED entity naming for multi-segment setups#169670mik-laj wants to merge 2 commits intohome-assistant:devfrom
Conversation
… WLED Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Hey there @frenck, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
There was a problem hiding this comment.
Pull request overview
This PR updates WLED entity naming so that when keep_main_light is enabled, the master light becomes the device-named entity and segment-based entities expose explicit segment-0 names instead of reusing the base device name.
Changes:
- Renames the WLED main light to use the device name when
keep_main_lightis enabled. - Applies segment-0-specific naming to WLED light, number, select, and switch entities when the main light is kept.
- Adds tests covering expected friendly names for single- and multi-segment devices with
keep_main_lightenabled and disabled.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
homeassistant/components/wled/light.py |
Updates main light and segment-0 light naming behavior when keep_main_light is enabled. |
homeassistant/components/wled/number.py |
Adds explicit segment translation keys and renames segment-0 number entities under keep_main_light. |
homeassistant/components/wled/select.py |
Renames segment-0 palette select when the main light is retained. |
homeassistant/components/wled/switch.py |
Renames segment-0 freeze/reverse switches when the main light is retained. |
tests/components/wled/test_light.py |
Replaces single-case light test with parametrized friendly-name assertions. |
tests/components/wled/test_number.py |
Adds parametrized friendly-name assertions for number entities. |
tests/components/wled/test_select.py |
Adds parametrized friendly-name assertions for select entities. |
tests/components/wled/test_switch.py |
Adds parametrized friendly-name assertions for switch entities. |
| if coordinator.keep_main_light: | ||
| self._attr_name = None |
There was a problem hiding this comment.
It is expected. I covered this scenario in PR description. Migration would be too risky.
arturpragacz
left a comment
There was a problem hiding this comment.
Changing segment 0's naming for users who never opted into keep_main_light would rename existing entities and silently break automations.
It would not break automations, unique_id remains the same.
|
|
||
| VERSION = 1 | ||
| MINOR_VERSION = 2 | ||
| MINOR_VERSION = 3 |
There was a problem hiding this comment.
This is intentional and consistent with how we handle options in other integration — storing no value distinguishes "user has never changed this setting" from "user explicitly set it to True/False". If we ever change DEFAULT_KEEP_MAIN_LIGHT again, we'll do it the same way we did here: write a migration that explicitly sets the option on all entries that should keep the old behavior, and let new entries inherit the new default. The 1.2 → 1.3 migration is exactly that pattern — it locks existing users to False rather than leaving them at the mercy of the constant.
| if coordinator.keep_main_light: | ||
| self._attr_name = None |
There was a problem hiding this comment.
For me, it's too risky to change an entity ID that's already assigned or to delete entities that have already been created. If the keep main light option is enabled, the entity will be marked as unavailable and the user can manually delete it from the UI.
There was a problem hiding this comment.
Besides, I think we should discourage disabling the "Keep Main Light" option and instead describe how to achieve a similar effect using automation. I even have such automations for multi-segment installations, and now there will also be a recommendation to use it for single-segment installations too.
One day, we might even retire the "Keep Main Light" option and leave it on by default but that's another thread.
|
@arturpragacz Yes and no. :-D HA has a mechanism to prevent this from breaking the automation by assigning an different entity ID and not changing the ID unless the unique ID changes. However, what I wanted to point out here is that the main entity is "light.wled" by convention (without suffixes). If we now want another entity to have this ID, so we cannot simply assign this ID to our entity, because it may break the automation, because the first segment already uses this ID. Home Assistant has a mechanism to handle this situation by creating an entity called "lgiht.wled_2", but this is a bit confusing as now the main entity ID doesn't follow convention. I've now looked into this issue deeper and enabled "main light" by default for new installs, so the IDs are now assigned correctly, and I think this approach is more in line with best practices. |
Part of: #124271.
Breaking change
No breaking change for existing installations — the migration sets
keep_main_light = False, preserving the current entity names and IDs.Users who had previously enabled Keep main light manually will see friendly name changes: the main light loses the "Main" suffix, and segment 0 gains a "Segment 0" qualifier. Entity IDs are not affected.
Problems solved
light.<device>for new installations, instead oflight.<device>_main.keep_main_light = True, all segments are named consistently.select.<device>_segment_0_color_palette,select.<device>_segment_1_color_palette, etc.keep_main_lightenabled by default — promotes the more idiomatic approach where the master controller and individual segments are separate entities, rather than merging both roles into segment 0.Proposed change
This PR makes the main light the primary entity when
keep_main_lightis enabled:WLEDMainLightgetsname = None→ uses the device name (e.g. "Garage Door Light"), becoming the true primary entity of the device.WLEDSegmentLightsegment 0 gets its proper "Segment 0" name (instead of inheriting the device name).keep_main_lightis nowTrueby default for new installations (config entry version 1.3). This ensures the main light registers first and naturally claimslight.<device>, avoiding entity ID collisions. It also brings the integration closer to best practices: the old default merged two distinct concepts into one entity (segment 0 acted as both segment and master controller). Withkeep_main_light = True, the main light controls the device and each segment controls only itself.Users with a single segment who prefer a simpler setup can still disable Keep Master Light in the integration options. In that mode, no main light entity is created, segment 0 becomes the primary entity (named after the device, without a "Segment 0" qualifier), and associated controls (color palette, speed, intensity, freeze, reverse) also drop the segment prefix.
Entity ID scenarios
All examples use a device named Garage Door Light.
New installation (v1.3,
keep_main_light = Trueby default)light.garage_door_light— main light (primary entity, controls the whole strip)light.garage_door_light_segment_0— segment 0light.garage_door_light_segment_1— segment 1 (if present)select.garage_door_light_segment_0_color_palette— color palette for segment 0select.garage_door_light_segment_1_color_palette— color palette for segment 1Existing single-segment installation upgrading from v1.2 (migration sets
keep_main_light = False)No entity IDs change. The migration preserves the current layout exactly:
light.garage_door_light— segment 0 (same as before, no main light entity)select.garage_door_light_color_palette— color palette for segment 0 (no segment qualifier)switch.garage_door_light_freeze— freeze for segment 0 (no segment qualifier)Existing single-segment installation upgrading from v1.2, then adding a second segment
After upgrade the user has
keep_main_light = Falseand segment 0 atlight.garage_door_light. When a second segment is added, the main light is created for the first time. Before this PR it would register aslight.garage_door_light_main(name = "Main"); after this PR it tries to claimlight.garage_door_light(name = None), but that is already taken by segment 0, so it lands onlight.garage_door_light_2:light.garage_door_light— segment 0 (frozen; withkeep_main_light = Falseit keeps no "Segment 0" qualifier)light.garage_door_light_2— main light (new entity; suffix becauselight.garage_door_lightis taken)light.garage_door_light_segment_1— segment 1 (new entity)select.garage_door_light_color_palette— color palette for segment 0 (frozen; no qualifier)select.garage_door_light_segment_1_color_palette— color palette for segment 1 (new entity)This is an edge case. Users who end up with
light.garage_door_light_2can rename it via the entity registry.Existing multi-segment installation upgrading from v1.2 (migration sets
keep_main_light = False)Nothing changes. With
keep_main_light = Falseand multiple segments, the main light still uses the "Main" translation key —name = Noneis only applied whenkeep_main_light = True. All entity IDs and friendly names remain exactly as before:light.garage_door_light_main— main light (unchanged)light.garage_door_light— segment 0 (unchanged)light.garage_door_light_segment_1— segment 1 (unchanged)select.garage_door_light_color_palette— color palette for segment 0 (unchanged)select.garage_door_light_segment_1_color_palette— color palette for segment 1 (unchanged)Existing installation where
keep_main_lightwas manually enabled before this PRAll entity IDs are frozen — only friendly names change. Before this PR, segment 0 never had a "Segment 0" qualifier regardless of
keep_main_light; this PR adds it for all segment 0 entities whenkeep_main_light = True.light.garage_door_light_main— main light; friendly name changes from "Garage Door Light Main" → "Garage Door Light"light.garage_door_light— segment 0; friendly name changes from "Garage Door Light" → "Garage Door Light Segment 0"select.garage_door_light_color_palette— segment 0 color palette; friendly name changes from "Color Palette" → "Segment 0 Color Palette"switch.garage_door_light_freeze— segment 0 freeze; friendly name changes from "Freeze" → "Segment 0 Freeze"number.garage_door_light_speed— segment 0 speed; friendly name changes from "Speed" → "Segment 0 Speed"New installation (v1.3) where the user later disables
keep_main_lightThe entity registry does not auto-remap entity IDs. After disabling the option:
light.garage_door_light— main light entity becomes unavailable (orphan in registry; unique_id = mac address)light.garage_door_light_segment_0— segment 0 stays at this ID; it does not reclaimlight.garage_door_lightselect.garage_door_light_color_palette— color palette for segment 0 becomes unavailable (orphan)select.garage_door_light_segment_0_color_palette— new entity for segment 0 color paletteThis is an edge case. The
keep_main_lightoption is designed for users who want a stable master entity; disabling it after initial setup is an unusual transition. Orphaned entities can be removed via the entity registry UI.Follow-up changes
To fully resolve the issues described in #124271, I plan two additional changes:
Type of change
Additional information
Checklist
ruff format homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all.To help with the load of incoming pull requests: