mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-22 11:13:34 +00:00
cli: print model, https, and lv for discover list (#1339)
``` kasa --target 192.168.xx.xx discover list HOST MODEL DEVICE FAMILY ENCRYPT HTTPS LV ALIAS 192.168.xxx.xxx KP115(EU) IOT.SMARTPLUGSWITCH XOR 0 - Fridge 192.168.xxx.xxx L900-5 SMART.TAPOBULB KLAP 0 2 L900 192.168.xxx.xxx P115 SMART.TAPOPLUG AES 0 2 Nightdesk 192.168.xxx.xxx TC65 SMART.IPCAMERA AES 1 2 Tapo_TC65_B593 ``` Also handles `TimeoutError` and `Exception` during `update()` --------- Co-authored-by: Steven B <51370195+sdb9696@users.noreply.github.com>
This commit is contained in:
parent
14d5629de1
commit
37ef7b0463
@ -123,14 +123,19 @@ async def list(ctx):
|
|||||||
async def print_discovered(dev: Device):
|
async def print_discovered(dev: Device):
|
||||||
cparams = dev.config.connection_type
|
cparams = dev.config.connection_type
|
||||||
infostr = (
|
infostr = (
|
||||||
f"{dev.host:<15} {cparams.device_family.value:<20} "
|
f"{dev.host:<15} {dev.model:<9} {cparams.device_family.value:<20} "
|
||||||
f"{cparams.encryption_type.value:<7}"
|
f"{cparams.encryption_type.value:<7} {cparams.https:<5} "
|
||||||
|
f"{cparams.login_version or '-':<3}"
|
||||||
)
|
)
|
||||||
async with sem:
|
async with sem:
|
||||||
try:
|
try:
|
||||||
await dev.update()
|
await dev.update()
|
||||||
except AuthenticationError:
|
except AuthenticationError:
|
||||||
echo(f"{infostr} - Authentication failed")
|
echo(f"{infostr} - Authentication failed")
|
||||||
|
except TimeoutError:
|
||||||
|
echo(f"{infostr} - Timed out")
|
||||||
|
except Exception as ex:
|
||||||
|
echo(f"{infostr} - Error: {ex}")
|
||||||
else:
|
else:
|
||||||
echo(f"{infostr} {dev.alias}")
|
echo(f"{infostr} {dev.alias}")
|
||||||
|
|
||||||
@ -138,7 +143,10 @@ async def list(ctx):
|
|||||||
if host := unsupported_exception.host:
|
if host := unsupported_exception.host:
|
||||||
echo(f"{host:<15} UNSUPPORTED DEVICE")
|
echo(f"{host:<15} UNSUPPORTED DEVICE")
|
||||||
|
|
||||||
echo(f"{'HOST':<15} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} {'ALIAS'}")
|
echo(
|
||||||
|
f"{'HOST':<15} {'MODEL':<9} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} "
|
||||||
|
f"{'HTTPS':<5} {'LV':<3} {'ALIAS'}"
|
||||||
|
)
|
||||||
return await _discover(
|
return await _discover(
|
||||||
ctx,
|
ctx,
|
||||||
print_discovered=print_discovered,
|
print_discovered=print_discovered,
|
||||||
|
@ -160,6 +160,17 @@ def create_discovery_mock(ip: str, fixture_data: dict):
|
|||||||
login_version: int | None = None
|
login_version: int | None = None
|
||||||
port_override: int | None = None
|
port_override: int | None = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def model(self) -> str:
|
||||||
|
dd = self.discovery_data
|
||||||
|
model_region = (
|
||||||
|
dd["result"]["device_model"]
|
||||||
|
if self.discovery_port == 20002
|
||||||
|
else dd["system"]["get_sysinfo"]["model"]
|
||||||
|
)
|
||||||
|
model, _, _ = model_region.partition("(")
|
||||||
|
return model
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _datagram(self) -> bytes:
|
def _datagram(self) -> bytes:
|
||||||
if self.default_port == 9999:
|
if self.default_port == 9999:
|
||||||
@ -178,7 +189,10 @@ def create_discovery_mock(ip: str, fixture_data: dict):
|
|||||||
"encrypt_type", discovery_result.get("encrypt_info", {}).get("sym_schm")
|
"encrypt_type", discovery_result.get("encrypt_info", {}).get("sym_schm")
|
||||||
)
|
)
|
||||||
|
|
||||||
login_version = discovery_result["mgt_encrypt_schm"].get("lv")
|
if not (login_version := discovery_result["mgt_encrypt_schm"].get("lv")) and (
|
||||||
|
et := discovery_result.get("encrypt_type")
|
||||||
|
):
|
||||||
|
login_version = max([int(i) for i in et])
|
||||||
https = discovery_result["mgt_encrypt_schm"]["is_support_https"]
|
https = discovery_result["mgt_encrypt_schm"]["is_support_https"]
|
||||||
dm = _DiscoveryMock(
|
dm = _DiscoveryMock(
|
||||||
ip,
|
ip,
|
||||||
|
@ -122,8 +122,15 @@ async def test_list_devices(discovery_mock, runner):
|
|||||||
catch_exceptions=False,
|
catch_exceptions=False,
|
||||||
)
|
)
|
||||||
assert res.exit_code == 0
|
assert res.exit_code == 0
|
||||||
header = f"{'HOST':<15} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} {'ALIAS'}"
|
header = (
|
||||||
row = f"{discovery_mock.ip:<15} {discovery_mock.device_type:<20} {discovery_mock.encrypt_type:<7}"
|
f"{'HOST':<15} {'MODEL':<9} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} "
|
||||||
|
f"{'HTTPS':<5} {'LV':<3} {'ALIAS'}"
|
||||||
|
)
|
||||||
|
row = (
|
||||||
|
f"{discovery_mock.ip:<15} {discovery_mock.model:<9} {discovery_mock.device_type:<20} "
|
||||||
|
f"{discovery_mock.encrypt_type:<7} {discovery_mock.https:<5} "
|
||||||
|
f"{discovery_mock.login_version or '-':<3}"
|
||||||
|
)
|
||||||
assert header in res.output
|
assert header in res.output
|
||||||
assert row in res.output
|
assert row in res.output
|
||||||
|
|
||||||
@ -158,14 +165,26 @@ async def test_discover_raw(discovery_mock, runner, mocker):
|
|||||||
redact_spy.assert_called()
|
redact_spy.assert_called()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("exception", "expected"),
|
||||||
|
[
|
||||||
|
pytest.param(
|
||||||
|
AuthenticationError("Failed to authenticate"),
|
||||||
|
"Authentication failed",
|
||||||
|
id="auth",
|
||||||
|
),
|
||||||
|
pytest.param(TimeoutError(), "Timed out", id="timeout"),
|
||||||
|
pytest.param(Exception("Foobar"), "Error: Foobar", id="other-error"),
|
||||||
|
],
|
||||||
|
)
|
||||||
@new_discovery
|
@new_discovery
|
||||||
async def test_list_auth_failed(discovery_mock, mocker, runner):
|
async def test_list_update_failed(discovery_mock, mocker, runner, exception, expected):
|
||||||
"""Test that device update is called on main."""
|
"""Test that device update is called on main."""
|
||||||
device_class = Discover._get_device_class(discovery_mock.discovery_data)
|
device_class = Discover._get_device_class(discovery_mock.discovery_data)
|
||||||
mocker.patch.object(
|
mocker.patch.object(
|
||||||
device_class,
|
device_class,
|
||||||
"update",
|
"update",
|
||||||
side_effect=AuthenticationError("Failed to authenticate"),
|
side_effect=exception,
|
||||||
)
|
)
|
||||||
res = await runner.invoke(
|
res = await runner.invoke(
|
||||||
cli,
|
cli,
|
||||||
@ -173,10 +192,17 @@ async def test_list_auth_failed(discovery_mock, mocker, runner):
|
|||||||
catch_exceptions=False,
|
catch_exceptions=False,
|
||||||
)
|
)
|
||||||
assert res.exit_code == 0
|
assert res.exit_code == 0
|
||||||
header = f"{'HOST':<15} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} {'ALIAS'}"
|
header = (
|
||||||
row = f"{discovery_mock.ip:<15} {discovery_mock.device_type:<20} {discovery_mock.encrypt_type:<7} - Authentication failed"
|
f"{'HOST':<15} {'MODEL':<9} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} "
|
||||||
assert header in res.output
|
f"{'HTTPS':<5} {'LV':<3} {'ALIAS'}"
|
||||||
assert row in res.output
|
)
|
||||||
|
row = (
|
||||||
|
f"{discovery_mock.ip:<15} {discovery_mock.model:<9} {discovery_mock.device_type:<20} "
|
||||||
|
f"{discovery_mock.encrypt_type:<7} {discovery_mock.https:<5} "
|
||||||
|
f"{discovery_mock.login_version or '-':<3} - {expected}"
|
||||||
|
)
|
||||||
|
assert header in res.output.replace("\n", "")
|
||||||
|
assert row in res.output.replace("\n", "")
|
||||||
|
|
||||||
|
|
||||||
async def test_list_unsupported(unsupported_device_info, runner):
|
async def test_list_unsupported(unsupported_device_info, runner):
|
||||||
@ -187,7 +213,10 @@ async def test_list_unsupported(unsupported_device_info, runner):
|
|||||||
catch_exceptions=False,
|
catch_exceptions=False,
|
||||||
)
|
)
|
||||||
assert res.exit_code == 0
|
assert res.exit_code == 0
|
||||||
header = f"{'HOST':<15} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} {'ALIAS'}"
|
header = (
|
||||||
|
f"{'HOST':<15} {'MODEL':<9} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} "
|
||||||
|
f"{'HTTPS':<5} {'LV':<3} {'ALIAS'}"
|
||||||
|
)
|
||||||
row = f"{'127.0.0.1':<15} UNSUPPORTED DEVICE"
|
row = f"{'127.0.0.1':<15} UNSUPPORTED DEVICE"
|
||||||
assert header in res.output
|
assert header in res.output
|
||||||
assert row in res.output
|
assert row in res.output
|
||||||
|
Loading…
Reference in New Issue
Block a user