Create common Time module and add time set cli command (#1157)

This commit is contained in:
Steven B.
2024-10-15 08:59:25 +01:00
committed by GitHub
parent 885a04d24f
commit 7fd8c14c1f
18 changed files with 350 additions and 69 deletions

View File

@@ -118,7 +118,6 @@ TIME_MODULE = {
"index": 12,
"tz_str": "test2",
},
"set_timezone": None,
}
CLOUD_MODULE = {
@@ -353,6 +352,19 @@ class FakeIotTransport(BaseTransport):
else:
return light_state
def set_time(self, new_state: dict, *args):
"""Implement set_time."""
mods = [
v
for k, v in self.proto.items()
if k in {"time", "smartlife.iot.common.timesetting"}
]
index = new_state.pop("index", None)
for mod in mods:
mod["get_time"] = new_state
if index is not None:
mod["get_timezone"]["index"] = index
baseproto = {
"system": {
"set_relay_state": set_relay_state,
@@ -391,8 +403,12 @@ class FakeIotTransport(BaseTransport):
"smartlife.iot.common.system": {
"set_dev_alias": set_alias,
},
"time": TIME_MODULE,
"smartlife.iot.common.timesetting": TIME_MODULE,
"time": {**TIME_MODULE, "set_time": set_time, "set_timezone": set_time},
"smartlife.iot.common.timesetting": {
**TIME_MODULE,
"set_time": set_time,
"set_timezone": set_time,
},
# HS220 brightness, different setter and getter
"smartlife.iot.dimmer": {
"set_brightness": set_hs220_brightness,

View File

@@ -1,11 +1,13 @@
import json
import os
import re
from datetime import datetime
import asyncclick as click
import pytest
from asyncclick.testing import CliRunner
from pytest_mock import MockerFixture
from zoneinfo import ZoneInfo
from kasa import (
AuthenticationError,
@@ -308,12 +310,8 @@ async def test_time_get(dev, runner):
assert "Current time: " in res.output
@device_smart
async def test_time_sync(dev, mocker, runner):
"""Test time sync command.
Currently implemented only for SMART.
"""
"""Test time sync command."""
update = mocker.patch.object(dev, "update")
set_time_mock = mocker.spy(dev.modules[Module.Time], "set_time")
res = await runner.invoke(
@@ -329,6 +327,48 @@ async def test_time_sync(dev, mocker, runner):
assert "New time: " in res.output
async def test_time_set(dev: Device, mocker, runner):
"""Test time set command."""
time_mod = dev.modules[Module.Time]
set_time_mock = mocker.spy(time_mod, "set_time")
dt = datetime(2024, 10, 15, 8, 15)
res = await runner.invoke(
time,
["set", str(dt.year), str(dt.month), str(dt.day), str(dt.hour), str(dt.minute)],
obj=dev,
)
set_time_mock.assert_called()
assert time_mod.time == dt.replace(tzinfo=time_mod.timezone)
assert res.exit_code == 0
assert "Old time: " in res.output
assert "New time: " in res.output
zone = ZoneInfo("Europe/Berlin")
dt = dt.replace(tzinfo=zone)
res = await runner.invoke(
time,
[
"set",
str(dt.year),
str(dt.month),
str(dt.day),
str(dt.hour),
str(dt.minute),
"--timezone",
zone.key,
],
input="y\n",
obj=dev,
)
assert time_mod.time == dt
assert res.exit_code == 0
assert "Old time: " in res.output
assert "New time: " in res.output
async def test_emeter(dev: Device, mocker, runner):
res = await runner.invoke(emeter, obj=dev)
if not dev.has_emeter:

View File

@@ -1,5 +1,9 @@
from datetime import datetime
import pytest
from freezegun.api import FrozenDateTimeFactory
from pytest_mock import MockerFixture
from zoneinfo import ZoneInfo
from kasa import Device, LightState, Module
from kasa.tests.device_fixtures import (
@@ -319,3 +323,24 @@ async def test_light_preset_save(dev: Device, mocker: MockerFixture):
assert new_preset_state.hue == new_preset.hue
assert new_preset_state.saturation == new_preset.saturation
assert new_preset_state.color_temp == new_preset.color_temp
async def test_set_time(dev: Device, freezer: FrozenDateTimeFactory):
"""Test setting the device time."""
freezer.move_to("2021-01-09 12:00:00+00:00")
time_mod = dev.modules[Module.Time]
tz_info = time_mod.timezone
now = datetime.now(tz=tz_info)
now = now.replace(microsecond=0)
assert time_mod.time != now
await time_mod.set_time(now)
await dev.update()
assert time_mod.time == now
zone = ZoneInfo("Europe/Berlin")
now = datetime.now(tz=zone)
now = now.replace(microsecond=0)
await time_mod.set_time(now)
await dev.update()
assert time_mod.time == now

View File

@@ -321,13 +321,14 @@ async def test_device_timezones():
# Get an index from a timezone
for index, zone in TIMEZONE_INDEX.items():
found_index = await get_timezone_index(zone)
zone_info = zoneinfo.ZoneInfo(zone)
found_index = await get_timezone_index(zone_info)
assert found_index == index
# Try a timezone not hardcoded finds another match
index = await get_timezone_index("Asia/Katmandu")
index = await get_timezone_index(zoneinfo.ZoneInfo("Asia/Katmandu"))
assert index == 77
# Try a timezone not hardcoded no match
with pytest.raises(zoneinfo.ZoneInfoNotFoundError):
await get_timezone_index("Foo/bar")
await get_timezone_index(zoneinfo.ZoneInfo("Foo/bar"))

View File

@@ -184,7 +184,7 @@ async def test_time(dev):
@device_iot
async def test_timezone(dev):
TZ_SCHEMA(await dev.get_timezone())
TZ_SCHEMA(await dev.modules[Module.Time].get_timezone())
@device_iot