1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-24 21:06:19 +00:00

Update WLED Select Options after update (#154205)

Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
This commit is contained in:
Kamil Breguła
2025-10-14 14:23:41 +02:00
committed by GitHub
parent d140eb4c76
commit 61a9094d5f
2 changed files with 117 additions and 16 deletions

View File

@@ -79,10 +79,6 @@ class WLEDPresetSelect(WLEDEntity, SelectEntity):
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"{coordinator.data.info.mac_address}_preset"
sorted_values = sorted(
coordinator.data.presets.values(), key=lambda preset: preset.name
)
self._attr_options = [preset.name for preset in sorted_values]
@property
def available(self) -> bool:
@@ -100,6 +96,14 @@ class WLEDPresetSelect(WLEDEntity, SelectEntity):
return preset.name
return None
@property
def options(self) -> list[str]:
"""Return a list of selectable options."""
sorted_values = sorted(
self.coordinator.data.presets.values(), key=lambda preset: preset.name
)
return [preset.name for preset in sorted_values]
@wled_exception_handler
async def async_select_option(self, option: str) -> None:
"""Set WLED segment to the selected preset."""
@@ -116,10 +120,6 @@ class WLEDPlaylistSelect(WLEDEntity, SelectEntity):
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"{coordinator.data.info.mac_address}_playlist"
sorted_values = sorted(
coordinator.data.playlists.values(), key=lambda playlist: playlist.name
)
self._attr_options = [playlist.name for playlist in sorted_values]
@property
def available(self) -> bool:
@@ -137,6 +137,14 @@ class WLEDPlaylistSelect(WLEDEntity, SelectEntity):
return playlist.name
return None
@property
def options(self) -> list[str]:
"""Return a list of selectable options."""
sorted_values = sorted(
self.coordinator.data.playlists.values(), key=lambda playlist: playlist.name
)
return [playlist.name for playlist in sorted_values]
@wled_exception_handler
async def async_select_option(self, option: str) -> None:
"""Set WLED segment to the selected playlist."""
@@ -161,10 +169,6 @@ class WLEDPaletteSelect(WLEDEntity, SelectEntity):
self._attr_translation_placeholders = {"segment": str(segment)}
self._attr_unique_id = f"{coordinator.data.info.mac_address}_palette_{segment}"
sorted_values = sorted(
coordinator.data.palettes.values(), key=lambda palette: palette.name
)
self._attr_options = [palette.name for palette in sorted_values]
self._segment = segment
@property
@@ -180,9 +184,22 @@ class WLEDPaletteSelect(WLEDEntity, SelectEntity):
@property
def current_option(self) -> str | None:
"""Return the current selected color palette."""
return self.coordinator.data.palettes[
int(self.coordinator.data.state.segments[self._segment].palette_id)
].name
if not self.coordinator.data.palettes:
return None
if (segment := self.coordinator.data.state.segments.get(self._segment)) is None:
return None
palette_id = int(segment.palette_id)
if (palette := self.coordinator.data.palettes.get(palette_id)) is None:
return None
return palette.name
@property
def options(self) -> list[str]:
"""Return a list of selectable options."""
sorted_values = sorted(
self.coordinator.data.palettes.values(), key=lambda palette: palette.name
)
return [palette.name for palette in sorted_values]
@wled_exception_handler
async def async_select_option(self, option: str) -> None:

View File

@@ -1,11 +1,19 @@
"""Tests for the WLED select platform."""
import typing
from unittest.mock import MagicMock
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy.assertion import SnapshotAssertion
from wled import Device as WLEDDevice, WLEDConnectionError, WLEDError
from wled import (
Device as WLEDDevice,
Palette as WLEDPalette,
Playlist as WLEDPlaylist,
Preset as WLEDPreset,
WLEDConnectionError,
WLEDError,
)
from homeassistant.components.select import ATTR_OPTION, DOMAIN as SELECT_DOMAIN
from homeassistant.components.wled.const import DOMAIN, SCAN_INTERVAL
@@ -168,3 +176,79 @@ async def test_playlist_unavailable_without_playlists(hass: HomeAssistant) -> No
"""Test WLED playlist entity is unavailable when playlists are not available."""
assert (state := hass.states.get("select.wled_rgb_light_playlist"))
assert state.state == STATE_UNAVAILABLE
PLAYLIST = {"ps": [1], "dur": [100], "transition": [7], "repeat": 0, "end": 0, "r": 0}
@pytest.mark.parametrize(
("entity_id", "data_attr", "new_data", "new_options"),
[
(
"select.wled_rgb_light_preset",
"presets",
{
1: WLEDPreset.from_dict({"preset_id": 1, "n": "Preset 1"}),
2: WLEDPreset.from_dict({"preset_id": 2, "n": "Preset 2"}),
},
["Preset 1", "Preset 2"],
),
(
"select.wled_rgb_light_playlist",
"playlists",
{
1: WLEDPlaylist.from_dict(
{"playlist_id": 1, "n": "Playlist 1", "playlist": PLAYLIST}
),
2: WLEDPlaylist.from_dict(
{"playlist_id": 2, "n": "Playlist 2", "playlist": PLAYLIST}
),
},
["Playlist 1", "Playlist 2"],
),
(
"select.wled_rgb_light_color_palette",
"palettes",
{
0: WLEDPalette.from_dict({"palette_id": 0, "name": "Palette 1"}),
1: WLEDPalette.from_dict({"palette_id": 1, "name": "Palette 2"}),
},
["Palette 1", "Palette 2"],
),
],
)
async def test_select_load_new_options_after_update(
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
mock_wled: MagicMock,
entity_id: str,
data_attr: str,
new_data: typing.Any,
new_options: list[str],
) -> None:
"""Test WLED select entity is updated when new options are added."""
setattr(
mock_wled.update.return_value,
data_attr,
{},
)
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
assert (state := hass.states.get(entity_id))
assert state.attributes["options"] == []
setattr(
mock_wled.update.return_value,
data_attr,
new_data,
)
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
assert (state := hass.states.get(entity_id))
assert state.attributes["options"] == new_options