Add HAOS scene preset buttons and smooth tutorial scrolling
Expose scene presets as button entities in the HA integration under a dedicated "Scenes" device. Each button activates its scene via the API. The coordinator now fetches scene presets alongside other data, and the integration reloads when the scene list changes. Also animate tutorial autoscroll with smooth behavior and wait for scrollend before positioning the spotlight overlay. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
75
custom_components/wled_screen_controller/button.py
Normal file
75
custom_components/wled_screen_controller/button.py
Normal file
@@ -0,0 +1,75 @@
|
||||
"""Button platform for LED Screen Controller — scene preset activation."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.button import ButtonEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import DOMAIN, DATA_COORDINATOR
|
||||
from .coordinator import WLEDScreenControllerCoordinator
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up scene preset buttons."""
|
||||
data = hass.data[DOMAIN][entry.entry_id]
|
||||
coordinator: WLEDScreenControllerCoordinator = data[DATA_COORDINATOR]
|
||||
|
||||
entities = []
|
||||
if coordinator.data:
|
||||
for preset in coordinator.data.get("scene_presets", []):
|
||||
entities.append(
|
||||
SceneActivateButton(coordinator, preset, entry.entry_id)
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class SceneActivateButton(CoordinatorEntity, ButtonEntity):
|
||||
"""Button that activates a scene preset."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: WLEDScreenControllerCoordinator,
|
||||
preset: dict[str, Any],
|
||||
entry_id: str,
|
||||
) -> None:
|
||||
"""Initialize the button."""
|
||||
super().__init__(coordinator)
|
||||
self._preset_id = preset["id"]
|
||||
self._entry_id = entry_id
|
||||
self._attr_unique_id = f"{entry_id}_scene_{preset['id']}"
|
||||
self._attr_translation_key = "activate_scene"
|
||||
self._attr_translation_placeholders = {"scene_name": preset["name"]}
|
||||
self._attr_icon = "mdi:palette"
|
||||
|
||||
@property
|
||||
def device_info(self) -> dict[str, Any]:
|
||||
"""Return device information — all scene buttons belong to the Scenes device."""
|
||||
return {"identifiers": {(DOMAIN, f"{self._entry_id}_scenes")}}
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return if entity is available."""
|
||||
if not self.coordinator.data:
|
||||
return False
|
||||
return any(
|
||||
p["id"] == self._preset_id
|
||||
for p in self.coordinator.data.get("scene_presets", [])
|
||||
)
|
||||
|
||||
async def async_press(self) -> None:
|
||||
"""Activate the scene preset."""
|
||||
await self.coordinator.activate_scene(self._preset_id)
|
||||
Reference in New Issue
Block a user