diff --git a/kasa/smart/modules/__init__.py b/kasa/smart/modules/__init__.py index 99820cfa..c1af2d4f 100644 --- a/kasa/smart/modules/__init__.py +++ b/kasa/smart/modules/__init__.py @@ -30,6 +30,7 @@ from .temperaturesensor import TemperatureSensor from .thermostat import Thermostat from .time import Time from .triggerlogs import TriggerLogs +from .vacuumspeaker import VacuumSpeaker from .waterleaksensor import WaterleakSensor __all__ = [ @@ -64,4 +65,5 @@ __all__ = [ "FrostProtection", "Thermostat", "SmartLightEffect", + "VacuumSpeaker", ] diff --git a/kasa/smart/modules/vacuumspeaker.py b/kasa/smart/modules/vacuumspeaker.py new file mode 100644 index 00000000..5730364c --- /dev/null +++ b/kasa/smart/modules/vacuumspeaker.py @@ -0,0 +1,70 @@ +"""Implementation of vacuum speaker.""" + +from __future__ import annotations + +import logging +from typing import TYPE_CHECKING + +from ...feature import Feature +from ..smartmodule import SmartModule + +if TYPE_CHECKING: + from ..smartdevice import SmartDevice + + +_LOGGER = logging.getLogger(__name__) + + +class VacuumSpeaker(SmartModule): + """Implementation of vacuum speaker.""" + + REQUIRED_COMPONENT = "speaker" + + def __init__(self, device: SmartDevice, module: str) -> None: + super().__init__(device, module) + self._add_feature( + Feature( + device, + id="vacuum_locate", + name="Locate vacuum", + container=self, + attribute_setter="locate", + category=Feature.Category.Primary, + type=Feature.Action, + ) + ) + self._add_feature( + Feature( + device, + id="vacuum_volume", + name="Volume", + container=self, + attribute_getter="volume", + attribute_setter="set_volume", + range_getter=lambda: (0, 100), + category=Feature.Category.Config, + type=Feature.Type.Number, + ) + ) + + def query(self) -> dict: + """Query to execute during the update cycle.""" + return { + "getVolume": None, + } + + @property + def volume(self) -> str: + """Return volume.""" + return self.data["volume"] + + async def set_volume(self, volume: int) -> dict: + """Set volume.""" + if volume < 0 or volume > 100: + raise ValueError("Volume must be between 0 and 100") + + return await self.call("setVolume", {"volume": volume}) + + async def locate(self) -> dict: + """Play sound to locate the device.""" + return await self.call("playSelectAudio", {"audio_type": "seek_me"})