Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions kasa/smartdevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,18 +291,33 @@ async def get_sys_info(self) -> Dict[str, Any]:
return await self._query_helper("system", "get_sysinfo")

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.update(self._create_request("system", "get_sysinfo"))

# Check for emeter if we were never updated, or if the device has emeter
if self._last_update is None or self.has_emeter:
# If this is the initial update, check only for the sysinfo
# This is necessary as some devices crash on unexpected modules
# 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)
# TODO: keep accessible for tests
self._sys_info = self._last_update["system"]["get_sysinfo"]

def update_from_discover_info(self, info):
Expand Down
2 changes: 1 addition & 1 deletion kasa/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
DIMMERS = {"HS220"}

DIMMABLE = {*BULBS, *DIMMERS}
WITH_EMETER = {"HS110", "HS300", *BULBS, *STRIPS}
WITH_EMETER = {"HS110", "HS300", *BULBS}

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

Expand Down
21 changes: 19 additions & 2 deletions kasa/tests/test_smartdevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

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


Expand All @@ -17,7 +17,24 @@ async def test_invalid_connection(dev):
with patch.object(FakeTransportProtocol, "query", side_effect=SmartDeviceException):
with pytest.raises(SmartDeviceException):
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):
Expand Down