Do not error when accessing smart device_type before update (#1319)

This commit is contained in:
Steven B. 2024-12-05 09:14:45 +00:00 committed by GitHub
parent 123ea107b1
commit 4eed945e00
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 36 additions and 5 deletions

View File

@ -765,10 +765,11 @@ class SmartDevice(Device):
if self._device_type is not DeviceType.Unknown:
return self._device_type
# Fallback to device_type (from disco info)
type_str = self._info.get("type", self._info.get("device_type"))
if not type_str: # no update or discovery info
if (
not (type_str := self._info.get("type", self._info.get("device_type")))
or not self._components
):
# no update or discovery info
return self._device_type
self._device_type = self._get_device_type_from_components(

View File

@ -130,6 +130,8 @@ new_discovery = parametrize_discovery(
"new discovery", data_root_filter="discovery_result"
)
smart_discovery = parametrize_discovery("smart discovery", protocol_filter={"SMART"})
@pytest.fixture(
params=filter_fixtures("discoverable", protocol_filter={"SMART", "IOT"}),

View File

@ -2,6 +2,7 @@
from __future__ import annotations
import copy
import logging
import time
from typing import Any, cast
@ -11,16 +12,18 @@ import pytest
from freezegun.api import FrozenDateTimeFactory
from pytest_mock import MockerFixture
from kasa import Device, KasaException, Module
from kasa import Device, DeviceType, KasaException, Module
from kasa.exceptions import DeviceError, SmartErrorCode
from kasa.protocols.smartprotocol import _ChildProtocolWrapper
from kasa.smart import SmartDevice
from kasa.smart.modules.energy import Energy
from kasa.smart.smartmodule import SmartModule
from tests.conftest import (
DISCOVERY_MOCK_IP,
device_smart,
get_device_for_fixture_protocol,
get_parent_and_child_modules,
smart_discovery,
)
from tests.device_fixtures import variable_temp_smart
@ -51,6 +54,31 @@ async def test_update_no_device_info(dev: SmartDevice, mocker: MockerFixture):
await dev.update()
@smart_discovery
async def test_device_type_no_update(discovery_mock, caplog: pytest.LogCaptureFixture):
"""Test device type and repr when device not updated."""
dev = SmartDevice(DISCOVERY_MOCK_IP)
assert dev.device_type is DeviceType.Unknown
assert repr(dev) == f"<DeviceType.Unknown at {DISCOVERY_MOCK_IP} - update() needed>"
discovery_result = copy.deepcopy(discovery_mock.discovery_data["result"])
dev.update_from_discover_info(discovery_result)
assert dev.device_type is DeviceType.Unknown
assert (
repr(dev)
== f"<DeviceType.Unknown at {DISCOVERY_MOCK_IP} - None (None) - update() needed>"
)
discovery_result["device_type"] = "SMART.FOOBAR"
dev.update_from_discover_info(discovery_result)
dev._components = {"dummy": 1}
assert dev.device_type is DeviceType.Plug
assert (
repr(dev)
== f"<DeviceType.Plug at {DISCOVERY_MOCK_IP} - None (None) - update() needed>"
)
assert "Unknown device type, falling back to plug" in caplog.text
@device_smart
async def test_initial_update(dev: SmartDevice, mocker: MockerFixture):
"""Test the initial update cycle."""