Skip to content

Fall back to UTC for iot time when the device clock is not set - #1768

Open
tk1475 wants to merge 1 commit into
python-kasa:masterfrom
tk1475:fix-unsynced-clock-timezone
Open

tk1475 wants to merge 1 commit into
python-kasa:masterfrom
tk1475:fix-unsynced-clock-timezone

Conversation

@tk1475

@tk1475 tk1475 commented Sep 25, 2026

Copy link
Copy Markdown

Fixes #1767

What was wrong

A new or factory-reset iot device can report a clock far in the past, e.g. year 2000. When the iot Time module can't use the configured zone index, _post_update_hook guesses a timezone from the difference between the device clock and host time. With an unset clock that difference is about 26 years. The last-resort timezone(offset) in _guess_timezone_by_offset then raises:

ValueError: offset must be a timedelta strictly between -timedelta(hours=24) and timedelta(hours=24), not datetime.timedelta(days=-9760, seconds=9900).

That exception breaks update(), so every cli command fails, including wifi scan and wifi join, which are the commands needed to provision the device.

Fix

In kasa/iot/modules/time.py, if the rounded delta is outside the range of real UTC offsets (-12h to +14h), treat the clock as unset and use UTC instead of guessing. The regular path, where the zone index resolves, is unchanged.

Testing

  • New test test_time_post_update_unsynced_clock_uses_utc in tests/test_common_modules.py. It runs over all iot device fixtures (@device_iot), sets the fake device's get_time to 2000-01-01 and forces the offset-based path. Without the fix, all 85 cases fail with the ValueError from the issue. With the fix, they pass.
  • uv run pytest -n auto: 23338 passed, 898 skipped
  • pre-commit run --files kasa/iot/modules/time.py tests/test_common_modules.py: all hooks pass (ruff, ruff-format, mypy, etc.)

I don't have an HS103 to test on, so I haven't confirmed provisioning end to end on real hardware.

Drafted with Claude Code; I reviewed the change and ran the tests myself.

🤖 Generated with Claude Code

An unprovisioned device can report a clock far in the past (e.g. year
2000). When its timezone has to be guessed from the offset to the host
time, the resulting delta is years long and timezone(offset) raises
"offset must be a timedelta strictly between -timedelta(hours=24) and
timedelta(hours=24)", which breaks update() and so every cli command.

Real UTC offsets range from -12h to +14h, so treat anything beyond that
as an unset clock and use UTC instead of guessing.

Fixes python-kasa#1767

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.31%. Comparing base (b7b41f2) to head (448aca3).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1768   +/-   ##
=======================================
  Coverage   93.31%   93.31%           
=======================================
  Files         158      158           
  Lines        9977     9980    +3     
  Branches     1025     1026    +1     
=======================================
+ Hits         9310     9313    +3     
  Misses        472      472           
  Partials      195      195           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@rytilahti rytilahti left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @tk1475!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"offset must be a timedelta" error when provisioning HS103

2 participants