FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Fix iotstrip child device time handling by ZeliardM · Pull Request #1584 · python-kasa/python-kasa · GitHub

Repository navigation

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .py  (3) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
17 changes: 17 additions & 0 deletions kasa/iot/iotstrip.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
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
Expand Down Expand Up @@ -349,6 +352,8 @@ async def _initialize_modules(self) -> None:
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."""
Expand Down Expand Up @@ -441,6 +446,18 @@ def led(self) -> bool:
"""
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:
Expand Down
5 changes: 5 additions & 0 deletions tests/device_fixtures.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,11 @@ def parametrize(
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"}
)
Expand Down
44 changes: 44 additions & 0 deletions tests/iot/test_iotstrip.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -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 == {}
Loading

Back | FazBrowse Home | New Git URL