mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-22 11:13:34 +00:00
Expose PIR enabled setting for iot dimmers (#1174)
This adds PIR enabled feature to iot dimmers, making it possible to enable and disable the motion detection.
This commit is contained in:
parent
530cf4b523
commit
9975bbf26a
@ -2,11 +2,15 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from enum import Enum
|
||||
|
||||
from ...exceptions import KasaException
|
||||
from ...feature import Feature
|
||||
from ..iotmodule import IotModule
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Range(Enum):
|
||||
"""Range for motion detection."""
|
||||
@ -17,27 +21,51 @@ class Range(Enum):
|
||||
Custom = 3
|
||||
|
||||
|
||||
# TODO: use the config reply in tests
|
||||
# {"enable":0,"version":"1.0","trigger_index":2,"cold_time":60000,
|
||||
# "min_adc":0,"max_adc":4095,"array":[80,50,20,0],"err_code":0}}}
|
||||
|
||||
|
||||
class Motion(IotModule):
|
||||
"""Implements the motion detection (PIR) module."""
|
||||
|
||||
def _initialize_features(self):
|
||||
"""Initialize features after the initial update."""
|
||||
# Only add features if the device supports the module
|
||||
if "get_config" not in self.data:
|
||||
return
|
||||
|
||||
if "enable" not in self.config:
|
||||
_LOGGER.warning("%r initialized, but no enable in response")
|
||||
return
|
||||
|
||||
self._add_feature(
|
||||
Feature(
|
||||
device=self._device,
|
||||
container=self,
|
||||
id="pir_enabled",
|
||||
name="PIR enabled",
|
||||
icon="mdi:motion-sensor",
|
||||
attribute_getter="enabled",
|
||||
attribute_setter="set_enabled",
|
||||
type=Feature.Type.Switch,
|
||||
category=Feature.Category.Config,
|
||||
)
|
||||
)
|
||||
|
||||
def query(self):
|
||||
"""Request PIR configuration."""
|
||||
return self.query_for_command("get_config")
|
||||
|
||||
@property
|
||||
def config(self) -> dict:
|
||||
"""Return current configuration."""
|
||||
return self.data["get_config"]
|
||||
|
||||
@property
|
||||
def range(self) -> Range:
|
||||
"""Return motion detection range."""
|
||||
return Range(self.data["trigger_index"])
|
||||
return Range(self.config["trigger_index"])
|
||||
|
||||
@property
|
||||
def enabled(self) -> bool:
|
||||
"""Return True if module is enabled."""
|
||||
return bool(self.data["enable"])
|
||||
return bool(self.config["enable"])
|
||||
|
||||
async def set_enabled(self, state: bool):
|
||||
"""Enable/disable PIR."""
|
||||
@ -63,7 +91,7 @@ class Motion(IotModule):
|
||||
@property
|
||||
def inactivity_timeout(self) -> int:
|
||||
"""Return inactivity timeout in milliseconds."""
|
||||
return self.data["cold_time"]
|
||||
return self.config["cold_time"]
|
||||
|
||||
async def set_inactivity_timeout(self, timeout: int):
|
||||
"""Set inactivity timeout in milliseconds.
|
||||
|
0
kasa/tests/iot/modules/__init__.py
Normal file
0
kasa/tests/iot/modules/__init__.py
Normal file
57
kasa/tests/iot/modules/test_motion.py
Normal file
57
kasa/tests/iot/modules/test_motion.py
Normal file
@ -0,0 +1,57 @@
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from kasa import Module
|
||||
from kasa.iot import IotDimmer
|
||||
from kasa.iot.modules.motion import Motion, Range
|
||||
from kasa.tests.device_fixtures import dimmer_iot
|
||||
|
||||
|
||||
@dimmer_iot
|
||||
def test_motion_getters(dev: IotDimmer):
|
||||
assert Module.IotMotion in dev.modules
|
||||
motion: Motion = dev.modules[Module.IotMotion]
|
||||
|
||||
assert motion.enabled == motion.config["enable"]
|
||||
assert motion.inactivity_timeout == motion.config["cold_time"]
|
||||
assert motion.range.value == motion.config["trigger_index"]
|
||||
|
||||
|
||||
@dimmer_iot
|
||||
async def test_motion_setters(dev: IotDimmer, mocker: MockerFixture):
|
||||
motion: Motion = dev.modules[Module.IotMotion]
|
||||
query_helper = mocker.patch("kasa.iot.IotDimmer._query_helper")
|
||||
|
||||
await motion.set_enabled(True)
|
||||
query_helper.assert_called_with("smartlife.iot.PIR", "set_enable", {"enable": True})
|
||||
|
||||
await motion.set_inactivity_timeout(10)
|
||||
query_helper.assert_called_with(
|
||||
"smartlife.iot.PIR", "set_cold_time", {"cold_time": 10}
|
||||
)
|
||||
|
||||
|
||||
@dimmer_iot
|
||||
async def test_motion_range(dev: IotDimmer, mocker: MockerFixture):
|
||||
motion: Motion = dev.modules[Module.IotMotion]
|
||||
query_helper = mocker.patch("kasa.iot.IotDimmer._query_helper")
|
||||
|
||||
await motion.set_range(custom_range=123)
|
||||
query_helper.assert_called_with(
|
||||
"smartlife.iot.PIR",
|
||||
"set_trigger_sens",
|
||||
{"index": Range.Custom.value, "value": 123},
|
||||
)
|
||||
|
||||
await motion.set_range(range=Range.Far)
|
||||
query_helper.assert_called_with(
|
||||
"smartlife.iot.PIR", "set_trigger_sens", {"index": Range.Far.value}
|
||||
)
|
||||
|
||||
|
||||
@dimmer_iot
|
||||
def test_motion_feature(dev: IotDimmer):
|
||||
assert Module.IotMotion in dev.modules
|
||||
motion: Motion = dev.modules[Module.IotMotion]
|
||||
|
||||
pir_enabled = dev.features["pir_enabled"]
|
||||
assert motion.enabled == pir_enabled.value
|
Loading…
Reference in New Issue
Block a user