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

Fall back to UTC for iot time when the device clock is not set by tk1475 · Pull Request #1768 · 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  (2) 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
7 changes: 6 additions & 1 deletion kasa/iot/modules/time.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 @@ -35,7 +35,7 @@ async def _post_update_hook(self) -> None:
If the configured zone is not available on this host, compute the device's
current UTC offset and choose a best-match available zone, preferring DST-
observing candidates when the original index implies DST. As a last resort,
use a fixed-offset timezone.
use a fixed-offset timezone. If the device clock is not set, use UTC.
"""
if res := self.data.get("get_timezone"):
idx = res.get("index")
Expand All @@ -58,6 +58,11 @@ async def _post_update_hook(self) -> None:
now_utc = datetime.now(UTC)
delta = device_local - now_utc.replace(tzinfo=None)
rounded = timedelta(seconds=60 * round(delta.total_seconds() / 60))
# UTC offsets range from -12h to +14h, anything beyond that means the
# device clock is not set (e.g. before provisioning).
if abs(rounded) > timedelta(hours=14):
self._timezone = UTC
return

dst_expected = None
if res := self.data.get("get_timezone"):
Expand Down
34 changes: 34 additions & 0 deletions tests/test_common_modules.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 @@ -513,6 +513,40 @@ async def test_time_post_update_uses_offset_when_index_missing_unit(
assert inst.timezone.utcoffset(now) == timedelta(0)


@device_iot
async def test_time_post_update_unsynced_clock_uses_utc(
dev: Device, mocker: MockerFixture
):
"""Fall back to UTC when the device clock is not set.

An unprovisioned device can report e.g. year 2000, which is no valid UTC offset
away from the host time, so the offset-based guess must not be attempted.
"""
from zoneinfo import ZoneInfoNotFoundError

proto = dev.protocol._transport.proto # type: ignore[attr-defined]
for target in ("time", "smartlife.iot.common.timesetting"):
if target in proto:
proto[target]["get_time"] = {
"year": 2000,
"month": 1,
"mday": 1,
"hour": 2,
"min": 45,
"sec": 0,
}
# Force the offset-based path, as when the zone is not available on the host
mocker.patch(
"kasa.iot.modules.time.get_timezone",
new=AsyncMock(side_effect=ZoneInfoNotFoundError("missing on host")),
)

await dev.update()
time_mod = dev.modules[Module.Time]
assert time_mod.timezone is UTC
assert time_mod.time.year == 2000


async def test_time_get_time_exception_returns_none_unit(mocker: MockerFixture):
"""Cover Time.get_time exception path (unit test of iot Time)."""
from kasa.iot.modules.time import Time as TimeModule
Expand Down
Loading

Back | FazBrowse Home | New Git URL