mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-01-08 22:07:06 +00:00
Perform initial update only using the sysinfo query (#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.
This commit is contained in:
parent
f8e7258b93
commit
b088596205
@ -291,18 +291,33 @@ class SmartDevice:
|
|||||||
return await self._query_helper("system", "get_sysinfo")
|
return await self._query_helper("system", "get_sysinfo")
|
||||||
|
|
||||||
async def update(self):
|
async def update(self):
|
||||||
"""Update some of the attributes.
|
"""Query the device to update the data.
|
||||||
|
|
||||||
Needed for methods that are decorated with `requires_update`.
|
Needed for properties that are decorated with `requires_update`.
|
||||||
"""
|
"""
|
||||||
req = {}
|
req = {}
|
||||||
req.update(self._create_request("system", "get_sysinfo"))
|
req.update(self._create_request("system", "get_sysinfo"))
|
||||||
|
|
||||||
# Check for emeter if we were never updated, or if the device has emeter
|
# If this is the initial update, check only for the sysinfo
|
||||||
if self._last_update is None or self.has_emeter:
|
# This is necessary as some devices crash on unexpected modules
|
||||||
req.update(self._create_emeter_request())
|
# See #105, #120, #161
|
||||||
|
if self._last_update is None:
|
||||||
|
_LOGGER.debug("Performing the initial update to obtain sysinfo")
|
||||||
|
self._last_update = await self.protocol.query(self.host, req)
|
||||||
|
self._sys_info = self._last_update["system"]["get_sysinfo"]
|
||||||
|
# If the device has no emeter, we are done for the initial update
|
||||||
|
# Otherwise we will follow the regular code path to also query
|
||||||
|
# the emeter data also during the initial update
|
||||||
|
if not self.has_emeter:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.has_emeter:
|
||||||
|
_LOGGER.debug(
|
||||||
|
"The device has emeter, querying its information along sysinfo"
|
||||||
|
)
|
||||||
|
req.update(self._create_emeter_request())
|
||||||
|
|
||||||
self._last_update = await self.protocol.query(self.host, req)
|
self._last_update = await self.protocol.query(self.host, req)
|
||||||
# TODO: keep accessible for tests
|
|
||||||
self._sys_info = self._last_update["system"]["get_sysinfo"]
|
self._sys_info = self._last_update["system"]["get_sysinfo"]
|
||||||
|
|
||||||
def update_from_discover_info(self, info):
|
def update_from_discover_info(self, info):
|
||||||
|
@ -35,7 +35,7 @@ STRIPS = {"HS107", "HS300", "KP303", "KP400"}
|
|||||||
DIMMERS = {"HS220"}
|
DIMMERS = {"HS220"}
|
||||||
|
|
||||||
DIMMABLE = {*BULBS, *DIMMERS}
|
DIMMABLE = {*BULBS, *DIMMERS}
|
||||||
WITH_EMETER = {"HS110", "HS300", *BULBS, *STRIPS}
|
WITH_EMETER = {"HS110", "HS300", *BULBS}
|
||||||
|
|
||||||
ALL_DEVICES = BULBS.union(PLUGS).union(STRIPS).union(DIMMERS)
|
ALL_DEVICES = BULBS.union(PLUGS).union(STRIPS).union(DIMMERS)
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import pytest # type: ignore # https://github.com/pytest-dev/pytest/issues/3342
|
|||||||
|
|
||||||
from kasa import SmartDeviceException
|
from kasa import SmartDeviceException
|
||||||
|
|
||||||
from .conftest import handle_turn_on, pytestmark, turn_on
|
from .conftest import handle_turn_on, has_emeter, no_emeter, pytestmark, turn_on
|
||||||
from .newfakes import PLUG_SCHEMA, TZ_SCHEMA, FakeTransportProtocol
|
from .newfakes import PLUG_SCHEMA, TZ_SCHEMA, FakeTransportProtocol
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,24 @@ async def test_invalid_connection(dev):
|
|||||||
with patch.object(FakeTransportProtocol, "query", side_effect=SmartDeviceException):
|
with patch.object(FakeTransportProtocol, "query", side_effect=SmartDeviceException):
|
||||||
with pytest.raises(SmartDeviceException):
|
with pytest.raises(SmartDeviceException):
|
||||||
await dev.update()
|
await dev.update()
|
||||||
dev.is_on
|
|
||||||
|
|
||||||
|
@has_emeter
|
||||||
|
async def test_initial_update_emeter(dev, mocker):
|
||||||
|
"""Test that the initial update performs second query if emeter is available."""
|
||||||
|
dev._last_update = None
|
||||||
|
spy = mocker.spy(dev.protocol, "query")
|
||||||
|
await dev.update()
|
||||||
|
assert spy.call_count == 2
|
||||||
|
|
||||||
|
|
||||||
|
@no_emeter
|
||||||
|
async def test_initial_update_no_emeter(dev, mocker):
|
||||||
|
"""Test that the initial update performs second query if emeter is available."""
|
||||||
|
dev._last_update = None
|
||||||
|
spy = mocker.spy(dev.protocol, "query")
|
||||||
|
await dev.update()
|
||||||
|
assert spy.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_query_helper(dev):
|
async def test_query_helper(dev):
|
||||||
|
Loading…
Reference in New Issue
Block a user