# Source code for kasa.interfaces.lighteffect

    """Interact with a TPLink Light Effect.

    >>> from kasa import Discover, Module, LightState
    >>>
    >>> dev = await Discover.discover_single(
    >>>     "127.0.0.3",
    >>>     username="user@example.com",
    >>>     password="great_password"
    >>> )
    >>> await dev.update()
    >>> print(dev.alias)
    Living Room Bulb

    Light effects are accessed via the LightPreset module. To list available presets

    >>> light_effect = dev.modules[Module.LightEffect]
    >>> light_effect.effect_list
    ['Off', 'Party', 'Relax']

    To view the currently selected effect:

    >>> light_effect.effect
    Off

    To activate a light effect:

    >>> await light_effect.set_effect("Party")
    >>> await dev.update()
    >>> light_effect.effect
    Party

    If the device supports it you can set custom effects:

    >>> if light_effect.has_custom_effects:
    >>>     effect_list = { "brightness", 50 }
    >>>     await light_effect.set_custom_effect(effect_list)
    >>> light_effect.has_custom_effects  # The device in this examples does not support \
    custom effects
    False
    """

    from __future__ import annotations

    from abc import ABC, abstractmethod

    from ..feature import Feature
    from ..module import Module

    class LightEffect(Module, ABC):
        """Interface to represent a light effect module."""

        LIGHT_EFFECTS_OFF = "Off"
        LIGHT_EFFECTS_UNNAMED_CUSTOM = "Custom"

        def _initialize_features(self) -> None:
            """Initialize features."""
            device = self._device
            self._add_feature(
                Feature(
                    device,
                    id="light_effect",
                    name="Light effect",
                    container=self,
                    attribute_getter="effect",
                    attribute_setter="set_effect",
                    category=Feature.Category.Primary,
                    type=Feature.Type.Choice,
                    choices_getter="effect_list",
                )
            )

        @property
        @abstractmethod
        def has_custom_effects(self) -> bool:
            """Return True if the device supports setting custom effects."""

        @property
        @abstractmethod
        def effect(self) -> str:
            """Return effect name."""

        @property
        @abstractmethod
        def effect_list(self) -> list[str]:
            """Return built-in effects list.

            Example:
                ['Aurora', 'Bubbling Cauldron', ...]
            """

        @abstractmethod
        async def set_effect(
            self,
            effect: str,
            *,
            brightness: int | None = None,
            transition: int | None = None,
        ) -> dict:
            """Set an effect on the device.

            If brightness or transition is defined,
            its value will be used instead of the effect-specific default.

            See :meth:`effect_list` for available effects,
            or use :meth:`set_custom_effect` for custom effects.

            :param str effect: The effect to set
            :param int brightness: The wanted brightness
            :param int transition: The wanted transition time
            """

        @abstractmethod
        async def set_custom_effect(
            self,
            effect_dict: dict,
        ) -> dict:
            """Set a custom effect on the device.

            :param str effect_dict: The custom effect dict to set
            """