mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-22 19:23: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
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
from ...exceptions import KasaException
|
from ...exceptions import KasaException
|
||||||
|
from ...feature import Feature
|
||||||
from ..iotmodule import IotModule
|
from ..iotmodule import IotModule
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Range(Enum):
|
class Range(Enum):
|
||||||
"""Range for motion detection."""
|
"""Range for motion detection."""
|
||||||
@ -17,27 +21,51 @@ class Range(Enum):
|
|||||||
Custom = 3
|
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):
|
class Motion(IotModule):
|
||||||
"""Implements the motion detection (PIR) module."""
|
"""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):
|
def query(self):
|
||||||
"""Request PIR configuration."""
|
"""Request PIR configuration."""
|
||||||
return self.query_for_command("get_config")
|
return self.query_for_command("get_config")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def config(self) -> dict:
|
||||||
|
"""Return current configuration."""
|
||||||
|
return self.data["get_config"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def range(self) -> Range:
|
def range(self) -> Range:
|
||||||
"""Return motion detection range."""
|
"""Return motion detection range."""
|
||||||
return Range(self.data["trigger_index"])
|
return Range(self.config["trigger_index"])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def enabled(self) -> bool:
|
def enabled(self) -> bool:
|
||||||
"""Return True if module is enabled."""
|
"""Return True if module is enabled."""
|
||||||
return bool(self.data["enable"])
|
return bool(self.config["enable"])
|
||||||
|
|
||||||
async def set_enabled(self, state: bool):
|
async def set_enabled(self, state: bool):
|
||||||
"""Enable/disable PIR."""
|
"""Enable/disable PIR."""
|
||||||
@ -63,7 +91,7 @@ class Motion(IotModule):
|
|||||||
@property
|
@property
|
||||||
def inactivity_timeout(self) -> int:
|
def inactivity_timeout(self) -> int:
|
||||||
"""Return inactivity timeout in milliseconds."""
|
"""Return inactivity timeout in milliseconds."""
|
||||||
return self.data["cold_time"]
|
return self.config["cold_time"]
|
||||||
|
|
||||||
async def set_inactivity_timeout(self, timeout: int):
|
async def set_inactivity_timeout(self, timeout: int):
|
||||||
"""Set inactivity timeout in milliseconds.
|
"""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