diff --git a/kasa/smartcam/modules/__init__.py b/kasa/smartcam/modules/__init__.py index 06130a374..14bd24f1e 100644 --- a/kasa/smartcam/modules/__init__.py +++ b/kasa/smartcam/modules/__init__.py @@ -13,6 +13,7 @@ from .motiondetection import MotionDetection from .pantilt import PanTilt from .persondetection import PersonDetection +from .petdetection import PetDetection from .tamperdetection import TamperDetection from .time import Time @@ -26,6 +27,7 @@ "Led", "PanTilt", "PersonDetection", + "PetDetection", "Time", "HomeKit", "Matter", diff --git a/kasa/smartcam/modules/petdetection.py b/kasa/smartcam/modules/petdetection.py new file mode 100644 index 000000000..2c7162304 --- /dev/null +++ b/kasa/smartcam/modules/petdetection.py @@ -0,0 +1,49 @@ +"""Implementation of pet detection module.""" + +from __future__ import annotations + +import logging + +from ...feature import Feature +from ...smart.smartmodule import allow_update_after +from ..smartcammodule import SmartCamModule + +_LOGGER = logging.getLogger(__name__) + + +class PetDetection(SmartCamModule): + """Implementation of pet detection module.""" + + REQUIRED_COMPONENT = "petDetection" + + QUERY_GETTER_NAME = "getPetDetectionConfig" + QUERY_MODULE_NAME = "pet_detection" + QUERY_SECTION_NAMES = "detection" + + def _initialize_features(self) -> None: + """Initialize features after the initial update.""" + self._add_feature( + Feature( + self._device, + id="pet_detection", + name="Pet detection", + container=self, + attribute_getter="enabled", + attribute_setter="set_enabled", + type=Feature.Type.Switch, + category=Feature.Category.Config, + ) + ) + + @property + def enabled(self) -> bool: + """Return the pet detection enabled state.""" + return self.data["detection"]["enabled"] == "on" + + @allow_update_after + async def set_enabled(self, enable: bool) -> dict: + """Set the pet detection enabled state.""" + params = {"enabled": "on" if enable else "off"} + return await self._device._query_setter_helper( + "setPetDetectionConfig", self.QUERY_MODULE_NAME, "detection", params + ) diff --git a/kasa/smartcam/smartcammodule.py b/kasa/smartcam/smartcammodule.py index 7b85680e5..ef00d47dc 100644 --- a/kasa/smartcam/smartcammodule.py +++ b/kasa/smartcam/smartcammodule.py @@ -26,6 +26,9 @@ class SmartCamModule(SmartModule): SmartCamPersonDetection: Final[ModuleName[modules.PersonDetection]] = ModuleName( "PersonDetection" ) + SmartCamPetDetection: Final[ModuleName[modules.PetDetection]] = ModuleName( + "PetDetection" + ) SmartCamTamperDetection: Final[ModuleName[modules.TamperDetection]] = ModuleName( "TamperDetection" ) diff --git a/tests/smartcam/modules/test_petdetection.py b/tests/smartcam/modules/test_petdetection.py new file mode 100644 index 000000000..6eff0c8af --- /dev/null +++ b/tests/smartcam/modules/test_petdetection.py @@ -0,0 +1,45 @@ +"""Tests for smartcam pet detection module.""" + +from __future__ import annotations + +from kasa import Device +from kasa.smartcam.smartcammodule import SmartCamModule + +from ...device_fixtures import parametrize + +petdetection = parametrize( + "has pet detection", + component_filter="petDetection", + protocol_filter={"SMARTCAM"}, +) + + +@petdetection +async def test_petdetection(dev: Device): + """Test device pet detection.""" + pet = dev.modules.get(SmartCamModule.SmartCamPetDetection) + assert pet + + pde_feat = dev.features.get("pet_detection") + assert pde_feat + + original_enabled = pet.enabled + + try: + await pet.set_enabled(not original_enabled) + await dev.update() + assert pet.enabled is not original_enabled + assert pde_feat.value is not original_enabled + + await pet.set_enabled(original_enabled) + await dev.update() + assert pet.enabled is original_enabled + assert pde_feat.value is original_enabled + + await pde_feat.set_value(not original_enabled) + await dev.update() + assert pet.enabled is not original_enabled + assert pde_feat.value is not original_enabled + + finally: + await pet.set_enabled(original_enabled)