HA integration: fix reload loop, parallel device fetch, WS guards, translations

- Fix indentation bug causing scenes device to not register
- Use nonlocal tracking to prevent infinite reload loops on target/scene changes
- Guard WS start/stop to avoid redundant connections
- Parallel device brightness fetching via asyncio.gather
- Route set_leds service to correct coordinator by source ID
- Remove stale pattern cache, reuse single timeout object
- Fix translations structure for light/select entities
- Unregister service when last config entry unloaded

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-19 11:21:46 +03:00
parent 122e95545c
commit 968046d96b
7 changed files with 105 additions and 70 deletions

View File

@@ -96,7 +96,7 @@ class CSSSourceSelect(CoordinatorEntity, SelectEntity):
return self._target_id in self.coordinator.data.get("targets", {})
async def async_select_option(self, option: str) -> None:
source_id = self._name_to_id(option)
source_id = self._name_to_id_map().get(option)
if source_id is None:
_LOGGER.error("CSS source not found: %s", option)
return
@@ -104,12 +104,9 @@ class CSSSourceSelect(CoordinatorEntity, SelectEntity):
self._target_id, color_strip_source_id=source_id
)
def _name_to_id(self, name: str) -> str | None:
def _name_to_id_map(self) -> dict[str, str]:
sources = (self.coordinator.data or {}).get("css_sources") or []
for s in sources:
if s["name"] == name:
return s["id"]
return None
return {s["name"]: s["id"] for s in sources}
class BrightnessSourceSelect(CoordinatorEntity, SelectEntity):
@@ -167,17 +164,14 @@ class BrightnessSourceSelect(CoordinatorEntity, SelectEntity):
if option == NONE_OPTION:
source_id = ""
else:
source_id = self._name_to_id(option)
name_map = {
s["name"]: s["id"]
for s in (self.coordinator.data or {}).get("value_sources") or []
}
source_id = name_map.get(option)
if source_id is None:
_LOGGER.error("Value source not found: %s", option)
return
await self.coordinator.update_target(
self._target_id, brightness_value_source_id=source_id
)
def _name_to_id(self, name: str) -> str | None:
sources = (self.coordinator.data or {}).get("value_sources") or []
for s in sources:
if s["name"] == name:
return s["id"]
return None