mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-08-09 20:24:02 +00:00
Create common Time module and add time set cli command (#1157)
This commit is contained in:
@@ -3,7 +3,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from datetime import datetime, tzinfo
|
||||
from datetime import datetime, timedelta, tzinfo
|
||||
from typing import cast
|
||||
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from ..cachedzoneinfo import CachedZoneInfo
|
||||
|
||||
@@ -22,26 +25,53 @@ async def get_timezone(index: int) -> tzinfo:
|
||||
return await CachedZoneInfo.get_cached_zone_info(name)
|
||||
|
||||
|
||||
async def get_timezone_index(name: str) -> int:
|
||||
async def get_timezone_index(tzone: tzinfo) -> int:
|
||||
"""Return the iot firmware index for a valid IANA timezone key."""
|
||||
rev = {val: key for key, val in TIMEZONE_INDEX.items()}
|
||||
if name in rev:
|
||||
return rev[name]
|
||||
if isinstance(tzone, ZoneInfo):
|
||||
name = tzone.key
|
||||
rev = {val: key for key, val in TIMEZONE_INDEX.items()}
|
||||
if name in rev:
|
||||
return rev[name]
|
||||
|
||||
# Try to find a supported timezone matching dst true/false
|
||||
zone = await CachedZoneInfo.get_cached_zone_info(name)
|
||||
now = datetime.now()
|
||||
winter = datetime(now.year, 1, 1, 12)
|
||||
summer = datetime(now.year, 7, 1, 12)
|
||||
for i in range(110):
|
||||
configured_zone = await get_timezone(i)
|
||||
if zone.utcoffset(winter) == configured_zone.utcoffset(
|
||||
winter
|
||||
) and zone.utcoffset(summer) == configured_zone.utcoffset(summer):
|
||||
if _is_same_timezone(tzone, await get_timezone(i)):
|
||||
return i
|
||||
raise ValueError("Device does not support timezone %s", name)
|
||||
|
||||
|
||||
async def get_matching_timezones(tzone: tzinfo) -> list[str]:
|
||||
"""Return the iot firmware index for a valid IANA timezone key."""
|
||||
matches = []
|
||||
if isinstance(tzone, ZoneInfo):
|
||||
name = tzone.key
|
||||
vals = {val for val in TIMEZONE_INDEX.values()}
|
||||
if name in vals:
|
||||
matches.append(name)
|
||||
|
||||
for i in range(110):
|
||||
fw_tz = await get_timezone(i)
|
||||
if _is_same_timezone(tzone, fw_tz):
|
||||
match_key = cast(ZoneInfo, fw_tz).key
|
||||
if match_key not in matches:
|
||||
matches.append(match_key)
|
||||
return matches
|
||||
|
||||
|
||||
def _is_same_timezone(tzone1: tzinfo, tzone2: tzinfo) -> bool:
|
||||
"""Return true if the timezones have the same utcffset and dst offset.
|
||||
|
||||
Iot devices only support a limited static list of IANA timezones; this is used to
|
||||
check if a static timezone matches the same utc offset and dst settings.
|
||||
"""
|
||||
now = datetime.now()
|
||||
start_day = datetime(now.year, 1, 1, 12)
|
||||
for i in range(365):
|
||||
the_day = start_day + timedelta(days=i)
|
||||
if tzone1.utcoffset(the_day) != tzone2.utcoffset(the_day):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
TIMEZONE_INDEX = {
|
||||
0: "Etc/GMT+12",
|
||||
1: "Pacific/Samoa",
|
||||
|
Reference in New Issue
Block a user