10000 Add exception for unsupported provisioning methods by rytilahti · Pull Request #1586 · python-kasa/python-kasa · GitHub
[go: up one dir, main page]

Skip to content
Draft
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
13 changes: 8 additions & 5 deletions kasa/cli/discover.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from kasa.protocols.iotprotocol import REDACTORS as IOT_REDACTORS
from kasa.protocols.protocol import redact_data

from ..exceptions import UnsupportedAuthenticationError
from ..json import dumps as json_dumps
from .common import echo, error

Expand Down Expand Up @@ -70,14 +71,16 @@ async def detail(ctx: click.Context) -> DeviceDict:
async def print_unsupported(unsupported_exception: UnsupportedDeviceError) -> None:
unsupported.append(unsupported_exception)
async with sem:
echo("== Unsupported device ==")
echo(f"\t{unsupported_exception}")
echo()

if unsupported_exception.discovery_result:
echo("== Unsupported device ==")
_echo_discovery_info(unsupported_exception.discovery_result)
echo()
else:
echo("== Unsupported device ==")
echo(f"\t{unsupported_exception}")
echo()
if isinstance(unsupported_exception, UnsupportedAuthenticationError):
echo("\t[red bold]Provisioned using unsupported 'tss'.[/red bold]")
echo("\tTo fix, reset and provision manually.")

from .device import state

Expand Down
10 changes: 9 additions & 1 deletion kasa/discover.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
from kasa.exceptions import (
KasaException,
TimeoutError,
UnsupportedAuthenticationError,
UnsupportedDeviceError,
)
from kasa.iot.iotdevice import IotDevice, _extract_sys_info
Expand Down Expand Up @@ -805,6 +806,13 @@ def _get_connection_parameters(
discovery_result: DiscoveryResult,
) -> DeviceConnectionParameters:
"""Get connection parameters from the discovery result."""
# Raise specific exception for unsupported authentication source
if getattr(discovery_result, "obd_src", None) == "tss":
raise UnsupportedAuthenticationError(
f"Device at {discovery_result.ip} uses unsupported onboarding 'tss'.",
discovery_result=discovery_result.to_dict(),
host=discovery_result.ip,
)
type_ = discovery_result.device_type
if (encrypt_schm := discovery_result.mgt_encrypt_schm) is None:
raise UnsupportedDeviceError(
Expand Down Expand Up @@ -885,7 +893,7 @@ def _get_device_instance(
conn_params = Discover._get_connection_parameters(discovery_result)
config.connection_type = conn_params
except KasaException as ex:
if isinstance(ex, UnsupportedDeviceError):
if isinstance(ex, UnsupportedDeviceError | UnsupportedAuthenticationError):
raise
raise UnsupportedDeviceError(
f"Unsupported device {config.host} of type {type_} "
Expand Down
8 changes: 8 additions & 0 deletions kasa/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,11 @@ def from_int(value: int) -> SmartErrorCode:
SmartErrorCode.TRANSPORT_UNKNOWN_CREDENTIALS_ERROR,
SmartErrorCode.HOMEKIT_LOGIN_FAIL,
]


class UnsupportedAuthenticationError(UnsupportedDeviceError, AuthenticationError):
"""Raised when authentication fails with unsupported provisioning method.

This can be used to display a more helpful message to the user when their devices
have been provisioned using the tplink simple setup (tss).
"""
18 changes: 18 additions & 0 deletions tests/discovery_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,3 +399,21 @@ async def mock_discover(self):
mocker.patch("kasa.discover._DiscoverProtocol.do_discover", mock_discover)

return discovery_data


def test_unsupported_authentication_exception_for_tss():
from kasa.discover import Discover, DiscoveryResult
from kasa.exceptions import UnsupportedAuthenticationError

# Create a mock discovery result with obd_src='tss'
dr = DiscoveryResult(
device_type="SomeType",
device_model="SomeModel",
device_id="SomeID",
ip="127.0.0.2",
mac="00:11:22:33:44:55",
obd_src="tss",
)
with pytest.raises(UnsupportedAuthenticationError) as excinfo:
Discover._get_connection_parameters(dr)
assert "obd_src='tss'" in str(excinfo.value)
Loading
0