8000 Perform initial update only using the sysinfo query (#199) · akshat-ja/python-kasa@b088596 · GitHub
[go: up one dir, main page]

Skip to content

Commit b088596

Browse files
authored
Perform initial update only using the sysinfo query (python-kasa#199)
Some devices are known to fail when trying to query non-supported modules like emeter information. This commit makes the initial update() only request the sysinfo, followed up by a second query if emeter is supported by the device.
1 parent f8e7258 commit b088596

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

kasa/smartdevice.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -291,18 +291,33 @@ async def get_sys_info(self) -> Dict[str, Any]:
291291
return await self._query_helper("system", "get_sysinfo")
292292

293293
async def update(self):
294-
"""Update some of the attributes.
294+
"""Query the device to update the data.
295295
296-
Needed for methods that are decorated with `requires_update`.
296+
Needed for properties that are decorated with `requires_update`.
297297
"""
298298
req = {}
299299
req.update(self._create_request("system", "get_sysinfo"))
300300

301-
# Check for emeter if we were never updated, or if the device has emeter
302-
if self._last_update is None or self.has_emeter:
301+
# If this is the initial update, check only for the sysinfo
302+
# This is necessary as some devices crash on unexpected modules
303+
# See #105, #120, #161
304+
if self._last_update is None:
305+
_LOGGER.debug("Performing the initial update to obtain sysinfo")
306+
self._last_update = await self.protocol.query(self.host, req)
307+
self._sys_info = self._last_update["system"]["get_sysinfo"]
308+
# If the device has no emeter, we are done for the initial update
309+
# Otherwise we will follow the regular code path to also query
310+
# the emeter data also during the initial update
311+
if not self.has_emeter:
312+
return
313+
314+
if self.has_emeter:
315+
_LOGGER.debug(
316+
"The device has emeter, querying its information along sysinfo"
317+
)
303318
req.update(self._create_emeter_request())
319+
304320
self._last_update = await self.protocol.query(self.host, req)
305-
# TODO: keep accessible for tests
306321
self._sys_info = self._last_update["system"]["get_sysinfo"]
307322

308323
def update_from_discover_info(self, info):

kasa/tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
DIMMERS = {"HS220"}
3636

3737
DIMMABLE = {*BULBS, *DIMMERS}
38-
WITH_EMETER = {"HS110", "HS300", *BULBS, *STRIPS}
38+
WITH_EMETER = {"HS110", "HS300", *BULBS}
3939

4040
ALL_DEVICES = BULBS.union(PLUGS).union(STRIPS).union(DIMMERS)
4141

kasa/tests/test_smartdevice.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from kasa import SmartDeviceException
77

8-
from .conftest import handle_turn_on, pytestmark, turn_on
8+
from .conftest import handle_turn_on, has_emeter, no_emeter, pytestmark, turn_on
99
from .newfakes import PLUG_SCHEMA, TZ_SCHEMA, FakeTransportProtocol
1010

1111

@@ -17,7 +17,24 @@ async def test_invalid_connection(dev):
1717
with patch.object(FakeTransportProtocol, "query", side_effect=SmartDeviceException):
1818
with pytest.raises(SmartDeviceException):
1919
await dev.update()
20-
dev.is_on
20+
21+
22+
@has_emeter
23+
async def test_initial_update_emeter(dev, mocker):
24+
"""Test that the initial update performs second query if emeter is available."""
25+
dev._last_update = None
26+
spy = mocker.spy(dev.protocol, "query")
27+
await dev.update()
28+
assert spy.call_count == 2
29+
30+
31+
@no_emeter
32+
async def test_initial_update_no_emeter(dev, mocker):
33+
"""Test that the initial update performs second query if emeter is available."""
34+
dev._last_update = None
35+
spy = mocker.spy(dev.protocol, "query")
36+
await dev.update()
37+
assert spy.call_count == 1
2138

2239

2340
async def test_query_helper(dev):

0 commit comments

Comments
 (0)
0