mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-11-05 23:21:56 +00:00
Fix iotstrip child device time handling (#1584)
Some checks failed
CI / Perform linting checks (3.13) (push) Has been cancelled
CodeQL checks / Analyze (python) (push) Has been cancelled
CI / Python 3.11 on macos-latest (push) Has been cancelled
CI / Python 3.12 on macos-latest (push) Has been cancelled
CI / Python 3.13 on macos-latest (push) Has been cancelled
CI / Python 3.11 on ubuntu-latest (push) Has been cancelled
CI / Python 3.12 on ubuntu-latest (push) Has been cancelled
CI / Python 3.13 on ubuntu-latest (push) Has been cancelled
CI / Python 3.11 on windows-latest (push) Has been cancelled
CI / Python 3.12 on windows-latest (push) Has been cancelled
CI / Python 3.13 on windows-latest (push) Has been cancelled
Stale / stale (push) Has been cancelled
Some checks failed
CI / Perform linting checks (3.13) (push) Has been cancelled
CodeQL checks / Analyze (python) (push) Has been cancelled
CI / Python 3.11 on macos-latest (push) Has been cancelled
CI / Python 3.12 on macos-latest (push) Has been cancelled
CI / Python 3.13 on macos-latest (push) Has been cancelled
CI / Python 3.11 on ubuntu-latest (push) Has been cancelled
CI / Python 3.12 on ubuntu-latest (push) Has been cancelled
CI / Python 3.13 on ubuntu-latest (push) Has been cancelled
CI / Python 3.11 on windows-latest (push) Has been cancelled
CI / Python 3.12 on windows-latest (push) Has been cancelled
CI / Python 3.13 on windows-latest (push) Has been cancelled
Stale / stale (push) Has been cancelled
This fixes the time handling of the child devices for iotstrip to pull from the parent device time module instead of having each child with its own time module.
This commit is contained in:
@@ -7,6 +7,9 @@ from collections import defaultdict
|
||||
from datetime import datetime, timedelta
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from datetime import tzinfo
|
||||
|
||||
from ..device_type import DeviceType
|
||||
from ..deviceconfig import DeviceConfig
|
||||
from ..emeterstatus import EmeterStatus
|
||||
@@ -349,6 +352,8 @@ class IotStripPlug(IotPlug):
|
||||
self.add_module(Module.IotAntitheft, Antitheft(self, "anti_theft"))
|
||||
self.add_module(Module.IotSchedule, Schedule(self, "schedule"))
|
||||
self.add_module(Module.IotCountdown, Countdown(self, "countdown"))
|
||||
# Note: do not add a Time module to the child; time is device-level.
|
||||
# Child exposes time/timezone by delegating to the parent.
|
||||
|
||||
async def _initialize_features(self) -> None:
|
||||
"""Initialize common features."""
|
||||
@@ -441,6 +446,18 @@ class IotStripPlug(IotPlug):
|
||||
"""
|
||||
return False
|
||||
|
||||
@property # type: ignore
|
||||
@requires_update
|
||||
def time(self) -> datetime:
|
||||
"""Return current time, delegated from the parent strip."""
|
||||
return self._parent.time
|
||||
|
||||
@property # type: ignore
|
||||
@requires_update
|
||||
def timezone(self) -> tzinfo:
|
||||
"""Return timezone, delegated from the parent strip."""
|
||||
return self._parent.timezone
|
||||
|
||||
@property # type: ignore
|
||||
@requires_update
|
||||
def device_id(self) -> str:
|
||||
|
||||
@@ -310,6 +310,11 @@ bulb = parametrize_combine([bulb_smart, bulb_iot])
|
||||
strip_iot = parametrize(
|
||||
"strip devices iot", model_filter=STRIPS_IOT, protocol_filter={"IOT"}
|
||||
)
|
||||
strip_emeter_iot = parametrize(
|
||||
"strip devices iot with emeter",
|
||||
model_filter=STRIPS_IOT & WITH_EMETER_IOT,
|
||||
protocol_filter={"IOT"},
|
||||
)
|
||||
strip_smart = parametrize(
|
||||
"strip devices smart", model_filter=STRIPS_SMART, protocol_filter={"SMART"}
|
||||
)
|
||||
|
||||
44
tests/iot/test_iotstrip.py
Normal file
44
tests/iot/test_iotstrip.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from kasa import Module
|
||||
from tests.conftest import strip_emeter_iot, strip_iot
|
||||
|
||||
|
||||
@strip_iot
|
||||
async def test_strip_update_and_child_update_behaviors(dev):
|
||||
await dev.update()
|
||||
await dev.update(update_children=False)
|
||||
|
||||
assert dev.children, "Expected strip device to have children"
|
||||
|
||||
child = dev.children[0]
|
||||
await child.update(update_children=False)
|
||||
|
||||
assert getattr(child, "_features", None)
|
||||
|
||||
|
||||
@strip_iot
|
||||
async def test_strip_child_delegated_properties(dev):
|
||||
await dev.update()
|
||||
child = dev.children[0]
|
||||
|
||||
assert child.led is False
|
||||
assert child.time == dev.time
|
||||
assert child.timezone == dev.timezone
|
||||
|
||||
na = child.next_action
|
||||
assert isinstance(na, dict)
|
||||
assert "type" in na
|
||||
|
||||
|
||||
@strip_emeter_iot
|
||||
async def test_strip_emeter_erase_stats(dev, mocker):
|
||||
await dev.update()
|
||||
|
||||
for child in dev.children:
|
||||
energy = child.modules.get(Module.Energy)
|
||||
if energy:
|
||||
mocker.patch.object(energy, "erase_stats", AsyncMock(return_value={}))
|
||||
|
||||
res = await dev.modules[Module.Energy].erase_stats()
|
||||
assert res == {}
|
||||
Reference in New Issue
Block a user