From 5eca487bcb8663313f8c56838a168e892fbfab92 Mon Sep 17 00:00:00 2001 From: "Steven B." <51370195+sdb9696@users.noreply.github.com> Date: Wed, 20 Nov 2024 13:34:26 +0000 Subject: [PATCH] Migrate iot cloud module to mashumaro (#1282) Breaking change as the CloudInfo interface is changing to snake case for consistency with the rest of the library. --- kasa/iot/modules/cloud.py | 29 +++++++++++++++++------------ tests/fakeprotocol_iot.py | 1 + tests/iot/modules/test_cloud.py | 13 +++++++++++++ 3 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 tests/iot/modules/test_cloud.py diff --git a/kasa/iot/modules/cloud.py b/kasa/iot/modules/cloud.py index 10097e64..d4e91a07 100644 --- a/kasa/iot/modules/cloud.py +++ b/kasa/iot/modules/cloud.py @@ -1,23 +1,28 @@ """Cloud module implementation.""" -from pydantic.v1 import BaseModel +from dataclasses import dataclass +from typing import Annotated + +from mashumaro import DataClassDictMixin +from mashumaro.types import Alias from ...feature import Feature from ..iotmodule import IotModule -class CloudInfo(BaseModel): +@dataclass +class CloudInfo(DataClassDictMixin): """Container for cloud settings.""" - binded: bool - cld_connection: int - fwDlPage: str - fwNotifyType: int - illegalType: int + provisioned: Annotated[int, Alias("binded")] + cloud_connected: Annotated[int, Alias("cld_connection")] + firmware_download_page: Annotated[str, Alias("fwDlPage")] + firmware_notify_type: Annotated[int, Alias("fwNotifyType")] + illegal_type: Annotated[int, Alias("illegalType")] server: str - stopConnect: int - tcspInfo: str - tcspStatus: int + stop_connect: Annotated[int, Alias("stopConnect")] + tcsp_info: Annotated[str, Alias("tcspInfo")] + tcsp_status: Annotated[int, Alias("tcspStatus")] username: str @@ -42,7 +47,7 @@ class Cloud(IotModule): @property def is_connected(self) -> bool: """Return true if device is connected to the cloud.""" - return self.info.binded + return bool(self.info.cloud_connected) def query(self) -> dict: """Request cloud connectivity info.""" @@ -51,7 +56,7 @@ class Cloud(IotModule): @property def info(self) -> CloudInfo: """Return information about the cloud connectivity.""" - return CloudInfo.parse_obj(self.data["get_info"]) + return CloudInfo.from_dict(self.data["get_info"]) def get_available_firmwares(self) -> dict: """Return list of available firmwares.""" diff --git a/tests/fakeprotocol_iot.py b/tests/fakeprotocol_iot.py index 8c4e4057..b4ce4b94 100644 --- a/tests/fakeprotocol_iot.py +++ b/tests/fakeprotocol_iot.py @@ -125,6 +125,7 @@ CLOUD_MODULE = { "username": "", "server": "devs.tplinkcloud.com", "binded": 0, + "err_code": 0, "cld_connection": 0, "illegalType": -1, "stopConnect": -1, diff --git a/tests/iot/modules/test_cloud.py b/tests/iot/modules/test_cloud.py new file mode 100644 index 00000000..ec7f8f83 --- /dev/null +++ b/tests/iot/modules/test_cloud.py @@ -0,0 +1,13 @@ +from kasa import Device, Module + +from ...device_fixtures import device_iot + + +@device_iot +def test_cloud(dev: Device): + cloud = dev.modules.get(Module.IotCloud) + assert cloud + info = cloud.info + assert info + assert isinstance(info.provisioned, int) + assert cloud.is_connected == bool(info.cloud_connected)