From 464683e09baa5302b7a43df533dd090b1aeaa792 Mon Sep 17 00:00:00 2001 From: "Steven B." <51370195+sdb9696@users.noreply.github.com> Date: Tue, 10 Dec 2024 21:23:04 +0000 Subject: [PATCH 1/5] Tweak RELEASING.md instructions for patch releases (#1347) --- RELEASING.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RELEASING.md b/RELEASING.md index 032aeb0c..e3527cea 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -283,9 +283,12 @@ git rebase upstream/master git checkout -b janitor/merge_patch git fetch upstream patch git merge upstream/patch --no-commit +# If there are any merge conflicts run the following command which will simply make master win +# Do not run it if there are no conflicts as it will end up checking out upstream/master git diff --name-only --diff-filter=U | xargs git checkout upstream/master +# Check the diff is as expected git diff --staged -# The only diff should be the version in pyproject.toml and CHANGELOG.md +# The only diff should be the version in pyproject.toml and uv.lock, and CHANGELOG.md # unless a change made on patch that was not part of a cherry-pick commit # If there are any other unexpected diffs `git checkout upstream/master [thefilename]` git commit -m "Merge patch into local master" -S From bf8f0adabe1ba1711bf76e9da18efa1f0554cf57 Mon Sep 17 00:00:00 2001 From: "Steven B." <51370195+sdb9696@users.noreply.github.com> Date: Tue, 10 Dec 2024 22:42:14 +0000 Subject: [PATCH 2/5] Return raw discovery result in cli discover raw (#1342) Add `on_discovered_raw` callback to Discover and adds a cli command `discover raw` which returns the raw json before serializing to a `DiscoveryResult` and attempting to create a device class. --- kasa/cli/discover.py | 54 +++++++++++++++++++++++++++--- kasa/discover.py | 79 ++++++++++++++++++++++++++++++++++++-------- kasa/json.py | 14 +++++--- tests/test_cli.py | 34 ++++++++++++++++++- 4 files changed, 158 insertions(+), 23 deletions(-) diff --git a/kasa/cli/discover.py b/kasa/cli/discover.py index f8967066..5e676a1d 100644 --- a/kasa/cli/discover.py +++ b/kasa/cli/discover.py @@ -14,9 +14,17 @@ from kasa import ( Discover, UnsupportedDeviceError, ) -from kasa.discover import ConnectAttempt, DiscoveryResult +from kasa.discover import ( + NEW_DISCOVERY_REDACTORS, + ConnectAttempt, + DiscoveredRaw, + DiscoveryResult, +) from kasa.iot.iotdevice import _extract_sys_info +from kasa.protocols.iotprotocol import REDACTORS as IOT_REDACTORS +from kasa.protocols.protocol import redact_data +from ..json import dumps as json_dumps from .common import echo, error @@ -64,7 +72,9 @@ async def detail(ctx): await ctx.parent.invoke(state) echo() - discovered = await _discover(ctx, print_discovered, print_unsupported) + discovered = await _discover( + ctx, print_discovered=print_discovered, print_unsupported=print_unsupported + ) if ctx.parent.parent.params["host"]: return discovered @@ -77,6 +87,33 @@ async def detail(ctx): return discovered +@discover.command() +@click.option( + "--redact/--no-redact", + default=False, + is_flag=True, + type=bool, + help="Set flag to redact sensitive data from raw output.", +) +@click.pass_context +async def raw(ctx, redact: bool): + """Return raw discovery data returned from devices.""" + + def print_raw(discovered: DiscoveredRaw): + if redact: + redactors = ( + NEW_DISCOVERY_REDACTORS + if discovered["meta"]["port"] == Discover.DISCOVERY_PORT_2 + else IOT_REDACTORS + ) + discovered["discovery_response"] = redact_data( + discovered["discovery_response"], redactors + ) + echo(json_dumps(discovered, indent=True)) + + return await _discover(ctx, print_raw=print_raw, do_echo=False) + + @discover.command() @click.pass_context async def list(ctx): @@ -102,10 +139,17 @@ async def list(ctx): echo(f"{host:<15} UNSUPPORTED DEVICE") echo(f"{'HOST':<15} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} {'ALIAS'}") - return await _discover(ctx, print_discovered, print_unsupported, do_echo=False) + return await _discover( + ctx, + print_discovered=print_discovered, + print_unsupported=print_unsupported, + do_echo=False, + ) -async def _discover(ctx, print_discovered, print_unsupported, *, do_echo=True): +async def _discover( + ctx, *, print_discovered=None, print_unsupported=None, print_raw=None, do_echo=True +): params = ctx.parent.parent.params target = params["target"] username = params["username"] @@ -126,6 +170,7 @@ async def _discover(ctx, print_discovered, print_unsupported, *, do_echo=True): timeout=timeout, discovery_timeout=discovery_timeout, on_unsupported=print_unsupported, + on_discovered_raw=print_raw, ) if do_echo: echo(f"Discovering devices on {target} for {discovery_timeout} seconds") @@ -137,6 +182,7 @@ async def _discover(ctx, print_discovered, print_unsupported, *, do_echo=True): port=port, timeout=timeout, credentials=credentials, + on_discovered_raw=print_raw, ) for device in discovered_devices.values(): diff --git a/kasa/discover.py b/kasa/discover.py index 9cb0808d..d88fcc09 100755 --- a/kasa/discover.py +++ b/kasa/discover.py @@ -99,6 +99,7 @@ from typing import ( Annotated, Any, NamedTuple, + TypedDict, cast, ) @@ -147,18 +148,35 @@ class ConnectAttempt(NamedTuple): device: type +class DiscoveredMeta(TypedDict): + """Meta info about discovery response.""" + + ip: str + port: int + + +class DiscoveredRaw(TypedDict): + """Try to connect attempt.""" + + meta: DiscoveredMeta + discovery_response: dict + + OnDiscoveredCallable = Callable[[Device], Coroutine] +OnDiscoveredRawCallable = Callable[[DiscoveredRaw], None] OnUnsupportedCallable = Callable[[UnsupportedDeviceError], Coroutine] OnConnectAttemptCallable = Callable[[ConnectAttempt, bool], None] DeviceDict = dict[str, Device] NEW_DISCOVERY_REDACTORS: dict[str, Callable[[Any], Any] | None] = { "device_id": lambda x: "REDACTED_" + x[9::], + "device_name": lambda x: "#MASKED_NAME#" if x else "", "owner": lambda x: "REDACTED_" + x[9::], "mac": mask_mac, "master_device_id": lambda x: "REDACTED_" + x[9::], "group_id": lambda x: "REDACTED_" + x[9::], "group_name": lambda x: "I01BU0tFRF9TU0lEIw==", + "encrypt_info": lambda x: {**x, "key": "", "data": ""}, } @@ -216,6 +234,7 @@ class _DiscoverProtocol(asyncio.DatagramProtocol): self, *, on_discovered: OnDiscoveredCallable | None = None, + on_discovered_raw: OnDiscoveredRawCallable | None = None, target: str = "255.255.255.255", discovery_packets: int = 3, discovery_timeout: int = 5, @@ -240,6 +259,7 @@ class _DiscoverProtocol(asyncio.DatagramProtocol): self.unsupported_device_exceptions: dict = {} self.invalid_device_exceptions: dict = {} self.on_unsupported = on_unsupported + self.on_discovered_raw = on_discovered_raw self.credentials = credentials self.timeout = timeout self.discovery_timeout = discovery_timeout @@ -329,12 +349,23 @@ class _DiscoverProtocol(asyncio.DatagramProtocol): config.timeout = self.timeout try: if port == self.discovery_port: - device = Discover._get_device_instance_legacy(data, config) + json_func = Discover._get_discovery_json_legacy + device_func = Discover._get_device_instance_legacy elif port == Discover.DISCOVERY_PORT_2: config.uses_http = True - device = Discover._get_device_instance(data, config) + json_func = Discover._get_discovery_json + device_func = Discover._get_device_instance else: return + info = json_func(data, ip) + if self.on_discovered_raw is not None: + self.on_discovered_raw( + { + "discovery_response": info, + "meta": {"ip": ip, "port": port}, + } + ) + device = device_func(info, config) except UnsupportedDeviceError as udex: _LOGGER.debug("Unsupported device found at %s << %s", ip, udex) self.unsupported_device_exceptions[ip] = udex @@ -391,6 +422,7 @@ class Discover: *, target: str = "255.255.255.255", on_discovered: OnDiscoveredCallable | None = None, + on_discovered_raw: OnDiscoveredRawCallable | None = None, discovery_timeout: int = 5, discovery_packets: int = 3, interface: str | None = None, @@ -421,6 +453,8 @@ class Discover: :param target: The target address where to send the broadcast discovery queries if multi-homing (e.g. 192.168.xxx.255). :param on_discovered: coroutine to execute on discovery + :param on_discovered_raw: Optional callback once discovered json is loaded + before any attempt to deserialize it and create devices :param discovery_timeout: Seconds to wait for responses, defaults to 5 :param discovery_packets: Number of discovery packets to broadcast :param interface: Bind to specific interface @@ -443,6 +477,7 @@ class Discover: discovery_packets=discovery_packets, interface=interface, on_unsupported=on_unsupported, + on_discovered_raw=on_discovered_raw, credentials=credentials, timeout=timeout, discovery_timeout=discovery_timeout, @@ -476,6 +511,7 @@ class Discover: credentials: Credentials | None = None, username: str | None = None, password: str | None = None, + on_discovered_raw: OnDiscoveredRawCallable | None = None, on_unsupported: OnUnsupportedCallable | None = None, ) -> Device | None: """Discover a single device by the given IP address. @@ -493,6 +529,9 @@ class Discover: username and password are ignored if provided. :param username: Username for devices that require authentication :param password: Password for devices that require authentication + :param on_discovered_raw: Optional callback once discovered json is loaded + before any attempt to deserialize it and create devices + :param on_unsupported: Optional callback when unsupported devices are discovered :rtype: SmartDevice :return: Object for querying/controlling found device. """ @@ -529,6 +568,7 @@ class Discover: credentials=credentials, timeout=timeout, discovery_timeout=discovery_timeout, + on_discovered_raw=on_discovered_raw, ), local_addr=("0.0.0.0", 0), # noqa: S104 ) @@ -666,15 +706,19 @@ class Discover: return get_device_class_from_sys_info(info) @staticmethod - def _get_device_instance_legacy(data: bytes, config: DeviceConfig) -> IotDevice: - """Get SmartDevice from legacy 9999 response.""" + def _get_discovery_json_legacy(data: bytes, ip: str) -> dict: + """Get discovery json from legacy 9999 response.""" try: info = json_loads(XorEncryption.decrypt(data)) except Exception as ex: raise KasaException( - f"Unable to read response from device: {config.host}: {ex}" + f"Unable to read response from device: {ip}: {ex}" ) from ex + return info + @staticmethod + def _get_device_instance_legacy(info: dict, config: DeviceConfig) -> Device: + """Get IotDevice from legacy 9999 response.""" if _LOGGER.isEnabledFor(logging.DEBUG): data = redact_data(info, IOT_REDACTORS) if Discover._redact_data else info _LOGGER.debug("[DISCOVERY] %s << %s", config.host, pf(data)) @@ -715,20 +759,25 @@ class Discover: discovery_result.decrypted_data = json_loads(decrypted_data) + @staticmethod + def _get_discovery_json(data: bytes, ip: str) -> dict: + """Get discovery json from the new 20002 response.""" + try: + info = json_loads(data[16:]) + except Exception as ex: + _LOGGER.debug("Got invalid response from device %s: %s", ip, data) + raise KasaException( + f"Unable to read response from device: {ip}: {ex}" + ) from ex + return info + @staticmethod def _get_device_instance( - data: bytes, + info: dict, config: DeviceConfig, ) -> Device: """Get SmartDevice from the new 20002 response.""" debug_enabled = _LOGGER.isEnabledFor(logging.DEBUG) - try: - info = json_loads(data[16:]) - except Exception as ex: - _LOGGER.debug("Got invalid response from device %s: %s", config.host, data) - raise KasaException( - f"Unable to read response from device: {config.host}: {ex}" - ) from ex try: discovery_result = DiscoveryResult.from_dict(info["result"]) @@ -757,7 +806,9 @@ class Discover: Discover._decrypt_discovery_data(discovery_result) except Exception: _LOGGER.exception( - "Unable to decrypt discovery data %s: %s", config.host, data + "Unable to decrypt discovery data %s: %s", + config.host, + redact_data(info, NEW_DISCOVERY_REDACTORS), ) type_ = discovery_result.device_type diff --git a/kasa/json.py b/kasa/json.py index 21c6fa00..8a0eab7b 100755 --- a/kasa/json.py +++ b/kasa/json.py @@ -8,18 +8,24 @@ from typing import Any try: import orjson - def dumps(obj: Any, *, default: Callable | None = None) -> str: + def dumps( + obj: Any, *, default: Callable | None = None, indent: bool = False + ) -> str: """Dump JSON.""" - return orjson.dumps(obj).decode() + return orjson.dumps( + obj, option=orjson.OPT_INDENT_2 if indent else None + ).decode() loads = orjson.loads except ImportError: import json - def dumps(obj: Any, *, default: Callable | None = None) -> str: + def dumps( + obj: Any, *, default: Callable | None = None, indent: bool = False + ) -> str: """Dump JSON.""" # Separators specified for consistency with orjson - return json.dumps(obj, separators=(",", ":")) + return json.dumps(obj, separators=(",", ":"), indent=2 if indent else None) loads = json.loads diff --git a/tests/test_cli.py b/tests/test_cli.py index d1fc330c..4391b998 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -42,8 +42,9 @@ from kasa.cli.main import TYPES, _legacy_type_to_class, cli, cmd_command, raw_co from kasa.cli.time import time from kasa.cli.usage import energy from kasa.cli.wifi import wifi -from kasa.discover import Discover, DiscoveryResult +from kasa.discover import Discover, DiscoveryResult, redact_data from kasa.iot import IotDevice +from kasa.json import dumps as json_dumps from kasa.smart import SmartDevice from kasa.smartcam import SmartCamDevice @@ -126,6 +127,36 @@ async def test_list_devices(discovery_mock, runner): assert row in res.output +async def test_discover_raw(discovery_mock, runner, mocker): + """Test the discover raw command.""" + redact_spy = mocker.patch( + "kasa.protocols.protocol.redact_data", side_effect=redact_data + ) + res = await runner.invoke( + cli, + ["--username", "foo", "--password", "bar", "discover", "raw"], + catch_exceptions=False, + ) + assert res.exit_code == 0 + + expected = { + "discovery_response": discovery_mock.discovery_data, + "meta": {"ip": "127.0.0.123", "port": discovery_mock.discovery_port}, + } + assert res.output == json_dumps(expected, indent=True) + "\n" + + redact_spy.assert_not_called() + + res = await runner.invoke( + cli, + ["--username", "foo", "--password", "bar", "discover", "raw", "--redact"], + catch_exceptions=False, + ) + assert res.exit_code == 0 + + redact_spy.assert_called() + + @new_discovery async def test_list_auth_failed(discovery_mock, mocker, runner): """Test that device update is called on main.""" @@ -731,6 +762,7 @@ async def test_without_device_type(dev, mocker, runner): timeout=5, discovery_timeout=7, on_unsupported=ANY, + on_discovered_raw=ANY, ) From 032cd5d2cc2004a3b161f124c441432a42b1bf1c Mon Sep 17 00:00:00 2001 From: "Teemu R." Date: Wed, 11 Dec 2024 01:01:36 +0100 Subject: [PATCH 3/5] Improve overheat reporting (#1335) Different devices and different firmwares report overheated status in different ways. Some devices indicate support for `overheat_protect` component, but there are devices that report `overheat_status` even when it is not listed. Some other devices use `overheated` boolean that was already previously supported, but this PR adds support for much more devices that use `overheat_status` for reporting. The "overheated" feature is moved into its own module, and uses either of the ways to report this information. This will also rename `REQUIRED_KEY_ON_PARENT` to `SYSINFO_LOOKUP_KEYS` and change its logic to check if any of the keys in the list are found in the sysinfo. ``` tpr@lumipyry ~/c/p/tests (fix/overheated)> ag 'overheat_protect' -c|wc -l 15 tpr@lumipyry ~/c/p/tests (fix/overheated)> ag 'overheated' -c|wc -l 38 tpr@lumipyry ~/c/p/tests (fix/overheated)> ag 'overheat_status' -c|wc -l 20 ``` --------- Co-authored-by: Steven B. <51370195+sdb9696@users.noreply.github.com> --- docs/tutorial.py | 2 +- kasa/feature.py | 2 +- kasa/smart/modules/__init__.py | 2 + kasa/smart/modules/contactsensor.py | 2 +- kasa/smart/modules/overheatprotection.py | 41 +++++++++++++++++ kasa/smart/smartdevice.py | 18 +------- kasa/smart/smartmodule.py | 4 +- tests/smart/test_smartdevice.py | 58 ++++++++++++++++++++++++ 8 files changed, 108 insertions(+), 21 deletions(-) create mode 100644 kasa/smart/modules/overheatprotection.py diff --git a/docs/tutorial.py b/docs/tutorial.py index 8d0a1435..f5cb9dea 100644 --- a/docs/tutorial.py +++ b/docs/tutorial.py @@ -91,5 +91,5 @@ False True >>> for feat in dev.features.values(): >>> print(f"{feat.name}: {feat.value}") -Device ID: 0000000000000000000000000000000000000000\nState: True\nSignal Level: 2\nRSSI: -52\nSSID: #MASKED_SSID#\nOverheated: False\nReboot: \nBrightness: 50\nCloud connection: True\nHSV: HSV(hue=0, saturation=100, value=50)\nColor temperature: 2700\nAuto update enabled: True\nUpdate available: None\nCurrent firmware version: 1.1.6 Build 240130 Rel.173828\nAvailable firmware version: None\nCheck latest firmware: \nLight effect: Party\nLight preset: Light preset 1\nSmooth transition on: 2\nSmooth transition off: 2\nDevice time: 2024-02-23 02:40:15+01:00 +Device ID: 0000000000000000000000000000000000000000\nState: True\nSignal Level: 2\nRSSI: -52\nSSID: #MASKED_SSID#\nReboot: \nBrightness: 50\nCloud connection: True\nHSV: HSV(hue=0, saturation=100, value=50)\nColor temperature: 2700\nAuto update enabled: True\nUpdate available: None\nCurrent firmware version: 1.1.6 Build 240130 Rel.173828\nAvailable firmware version: None\nCheck latest firmware: \nLight effect: Party\nLight preset: Light preset 1\nSmooth transition on: 2\nSmooth transition off: 2\nOverheated: False\nDevice time: 2024-02-23 02:40:15+01:00 """ diff --git a/kasa/feature.py b/kasa/feature.py index d747338d..ff19baf9 100644 --- a/kasa/feature.py +++ b/kasa/feature.py @@ -24,7 +24,6 @@ State (state): True Signal Level (signal_level): 2 RSSI (rssi): -52 SSID (ssid): #MASKED_SSID# -Overheated (overheated): False Reboot (reboot): Brightness (brightness): 100 Cloud connection (cloud_connection): True @@ -39,6 +38,7 @@ Light effect (light_effect): Off Light preset (light_preset): Not set Smooth transition on (smooth_transition_on): 2 Smooth transition off (smooth_transition_off): 2 +Overheated (overheated): False Device time (device_time): 2024-02-23 02:40:15+01:00 To see whether a device supports a feature, check for the existence of it: diff --git a/kasa/smart/modules/__init__.py b/kasa/smart/modules/__init__.py index 99820cfa..36754801 100644 --- a/kasa/smart/modules/__init__.py +++ b/kasa/smart/modules/__init__.py @@ -24,6 +24,7 @@ from .lightpreset import LightPreset from .lightstripeffect import LightStripEffect from .lighttransition import LightTransition from .motionsensor import MotionSensor +from .overheatprotection import OverheatProtection from .reportmode import ReportMode from .temperaturecontrol import TemperatureControl from .temperaturesensor import TemperatureSensor @@ -64,4 +65,5 @@ __all__ = [ "FrostProtection", "Thermostat", "SmartLightEffect", + "OverheatProtection", ] diff --git a/kasa/smart/modules/contactsensor.py b/kasa/smart/modules/contactsensor.py index f388b781..d0bebb07 100644 --- a/kasa/smart/modules/contactsensor.py +++ b/kasa/smart/modules/contactsensor.py @@ -10,7 +10,7 @@ class ContactSensor(SmartModule): """Implementation of contact sensor module.""" REQUIRED_COMPONENT = None # we depend on availability of key - REQUIRED_KEY_ON_PARENT = "open" + SYSINFO_LOOKUP_KEYS = ["open"] def _initialize_features(self) -> None: """Initialize features after the initial update.""" diff --git a/kasa/smart/modules/overheatprotection.py b/kasa/smart/modules/overheatprotection.py new file mode 100644 index 00000000..cdaba4e8 --- /dev/null +++ b/kasa/smart/modules/overheatprotection.py @@ -0,0 +1,41 @@ +"""Overheat module.""" + +from __future__ import annotations + +from ...feature import Feature +from ..smartmodule import SmartModule + + +class OverheatProtection(SmartModule): + """Implementation for overheat_protection.""" + + SYSINFO_LOOKUP_KEYS = ["overheated", "overheat_status"] + + def _initialize_features(self) -> None: + """Initialize features after the initial update.""" + self._add_feature( + Feature( + self._device, + container=self, + id="overheated", + name="Overheated", + attribute_getter="overheated", + icon="mdi:heat-wave", + type=Feature.Type.BinarySensor, + category=Feature.Category.Info, + ) + ) + + @property + def overheated(self) -> bool: + """Return True if device reports overheating.""" + if (value := self._device.sys_info.get("overheat_status")) is not None: + # Value can be normal, cooldown, or overheated. + # We report all but normal as overheated. + return value != "normal" + + return self._device.sys_info["overheated"] + + def query(self) -> dict: + """Query to execute during the update cycle.""" + return {} diff --git a/kasa/smart/smartdevice.py b/kasa/smart/smartdevice.py index 48f50c0e..ed5a4eec 100644 --- a/kasa/smart/smartdevice.py +++ b/kasa/smart/smartdevice.py @@ -349,9 +349,8 @@ class SmartDevice(Device): ) or mod.__name__ in child_modules_to_skip: continue required_component = cast(str, mod.REQUIRED_COMPONENT) - if required_component in self._components or ( - mod.REQUIRED_KEY_ON_PARENT - and self.sys_info.get(mod.REQUIRED_KEY_ON_PARENT) is not None + if required_component in self._components or any( + self.sys_info.get(key) is not None for key in mod.SYSINFO_LOOKUP_KEYS ): _LOGGER.debug( "Device %s, found required %s, adding %s to modules.", @@ -440,19 +439,6 @@ class SmartDevice(Device): ) ) - if "overheated" in self._info: - self._add_feature( - Feature( - self, - id="overheated", - name="Overheated", - attribute_getter=lambda x: x._info["overheated"], - icon="mdi:heat-wave", - type=Feature.Type.BinarySensor, - category=Feature.Category.Info, - ) - ) - # We check for the key available, and not for the property truthiness, # as the value is falsy when the device is off. if "on_time" in self._info: diff --git a/kasa/smart/smartmodule.py b/kasa/smart/smartmodule.py index c5697043..ab6ae667 100644 --- a/kasa/smart/smartmodule.py +++ b/kasa/smart/smartmodule.py @@ -54,8 +54,8 @@ class SmartModule(Module): NAME: str #: Module is initialized, if the given component is available REQUIRED_COMPONENT: str | None = None - #: Module is initialized, if the given key available in the main sysinfo - REQUIRED_KEY_ON_PARENT: str | None = None + #: Module is initialized, if any of the given keys exists in the sysinfo + SYSINFO_LOOKUP_KEYS: list[str] = [] #: Query to execute during the main update cycle QUERY_GETTER_NAME: str diff --git a/tests/smart/test_smartdevice.py b/tests/smart/test_smartdevice.py index 81707a11..25addcfc 100644 --- a/tests/smart/test_smartdevice.py +++ b/tests/smart/test_smartdevice.py @@ -470,3 +470,61 @@ async def test_smart_temp_range(dev: Device): light = dev.modules.get(Module.Light) assert light assert light.valid_temperature_range + + +@device_smart +async def test_initialize_modules_sysinfo_lookup_keys( + dev: SmartDevice, mocker: MockerFixture +): + """Test that matching modules using SYSINFO_LOOKUP_KEYS are initialized correctly.""" + + class AvailableKey(SmartModule): + SYSINFO_LOOKUP_KEYS = ["device_id"] + + class NonExistingKey(SmartModule): + SYSINFO_LOOKUP_KEYS = ["this_does_not_exist"] + + # The __init_subclass__ hook in smartmodule checks the path, + # so we have to manually add these for testing. + mocker.patch.dict( + "kasa.smart.smartmodule.SmartModule.REGISTERED_MODULES", + { + AvailableKey._module_name(): AvailableKey, + NonExistingKey._module_name(): NonExistingKey, + }, + ) + + # We have an already initialized device, so we try to initialize the modules again + await dev._initialize_modules() + + assert "AvailableKey" in dev.modules + assert "NonExistingKey" not in dev.modules + + +@device_smart +async def test_initialize_modules_required_component( + dev: SmartDevice, mocker: MockerFixture +): + """Test that matching modules using REQUIRED_COMPONENT are initialized correctly.""" + + class AvailableComponent(SmartModule): + REQUIRED_COMPONENT = "device" + + class NonExistingComponent(SmartModule): + REQUIRED_COMPONENT = "this_does_not_exist" + + # The __init_subclass__ hook in smartmodule checks the path, + # so we have to manually add these for testing. + mocker.patch.dict( + "kasa.smart.smartmodule.SmartModule.REGISTERED_MODULES", + { + AvailableComponent._module_name(): AvailableComponent, + NonExistingComponent._module_name(): NonExistingComponent, + }, + ) + + # We have an already initialized device, so we try to initialize the modules again + await dev._initialize_modules() + + assert "AvailableComponent" in dev.modules + assert "NonExistingComponent" not in dev.modules From 8cb5c2e180ef8113bed9360bd29e88837f911d0f Mon Sep 17 00:00:00 2001 From: "Steven B." <51370195+sdb9696@users.noreply.github.com> Date: Wed, 11 Dec 2024 13:18:44 +0000 Subject: [PATCH 4/5] Update dump_devinfo for raw discovery json and common redactors (#1358) This PR does a few related things to dump_devinfo: - Store the raw discovery result in the fixture. - Consolidate redaction logic so it's not duplicated in dump_devinfo. - Update existing fixtures to: - Store raw discovery result under `result` - Use `SCRUBBED_CHILD_DEVICE_ID` everywhere - Have correct values as per the consolidated redactors. --- devtools/dump_devinfo.py | 220 ++++++++---------- devtools/generate_supported.py | 2 +- devtools/update_fixtures.py | 128 ++++++++++ kasa/discover.py | 23 +- kasa/protocols/iotprotocol.py | 18 +- kasa/protocols/protocol.py | 2 + kasa/protocols/smartprotocol.py | 27 ++- tests/device_fixtures.py | 2 +- tests/discovery_fixtures.py | 9 +- tests/fixtures/iot/EP10(US)_1.0_1.0.2.json | 2 +- tests/fixtures/iot/EP40(US)_1.0_1.0.2.json | 10 +- tests/fixtures/iot/ES20M(US)_1.0_1.0.11.json | 2 +- tests/fixtures/iot/ES20M(US)_1.0_1.0.8.json | 2 +- tests/fixtures/iot/HS100(UK)_4.1_1.1.0.json | 29 +-- tests/fixtures/iot/HS100(US)_1.0_1.2.5.json | 2 +- tests/fixtures/iot/HS100(US)_2.0_1.5.6.json | 2 +- tests/fixtures/iot/HS103(US)_1.0_1.5.7.json | 2 +- tests/fixtures/iot/HS103(US)_2.1_1.1.2.json | 2 +- tests/fixtures/iot/HS103(US)_2.1_1.1.4.json | 2 +- tests/fixtures/iot/HS105(US)_1.0_1.5.6.json | 2 +- tests/fixtures/iot/HS107(US)_1.0_1.0.8.json | 12 +- tests/fixtures/iot/HS110(EU)_1.0_1.2.5.json | 2 +- tests/fixtures/iot/HS110(US)_1.0_1.2.6.json | 2 +- tests/fixtures/iot/HS200(US)_2.0_1.5.7.json | 2 +- tests/fixtures/iot/HS200(US)_5.0_1.0.2.json | 2 +- tests/fixtures/iot/HS210(US)_1.0_1.5.8.json | 2 +- tests/fixtures/iot/HS220(US)_1.0_1.5.7.json | 6 +- tests/fixtures/iot/HS220(US)_2.0_1.0.3.json | 2 +- tests/fixtures/iot/HS300(US)_1.0_1.0.10.json | 28 +-- tests/fixtures/iot/HS300(US)_1.0_1.0.21.json | 26 +-- tests/fixtures/iot/HS300(US)_2.0_1.0.12.json | 24 +- tests/fixtures/iot/HS300(US)_2.0_1.0.3.json | 26 +-- tests/fixtures/iot/KL110(US)_1.0_1.8.11.json | 2 +- tests/fixtures/iot/KL120(US)_1.0_1.8.11.json | 2 +- tests/fixtures/iot/KL120(US)_1.0_1.8.6.json | 8 +- tests/fixtures/iot/KL125(US)_1.20_1.0.5.json | 2 +- tests/fixtures/iot/KL125(US)_2.0_1.0.7.json | 2 +- tests/fixtures/iot/KL130(EU)_1.0_1.8.8.json | 2 +- tests/fixtures/iot/KL130(US)_1.0_1.8.11.json | 2 +- tests/fixtures/iot/KL135(US)_1.0_1.0.15.json | 2 +- tests/fixtures/iot/KL135(US)_1.0_1.0.6.json | 2 +- tests/fixtures/iot/KL400L5(US)_1.0_1.0.5.json | 2 +- tests/fixtures/iot/KL400L5(US)_1.0_1.0.8.json | 2 +- tests/fixtures/iot/KL420L5(US)_1.0_1.0.2.json | 2 +- tests/fixtures/iot/KL430(UN)_2.0_1.0.8.json | 2 +- tests/fixtures/iot/KL430(US)_1.0_1.0.10.json | 2 +- tests/fixtures/iot/KL430(US)_2.0_1.0.11.json | 2 +- tests/fixtures/iot/KL430(US)_2.0_1.0.8.json | 2 +- tests/fixtures/iot/KL430(US)_2.0_1.0.9.json | 2 +- tests/fixtures/iot/KL50(US)_1.0_1.1.13.json | 2 +- tests/fixtures/iot/KL60(UN)_1.0_1.1.4.json | 4 +- tests/fixtures/iot/KL60(US)_1.0_1.1.13.json | 2 +- tests/fixtures/iot/KP100(US)_3.0_1.0.1.json | 2 +- tests/fixtures/iot/KP105(UK)_1.0_1.0.5.json | 2 +- tests/fixtures/iot/KP115(US)_1.0_1.0.17.json | 2 +- tests/fixtures/iot/KP125(US)_1.0_1.0.6.json | 2 +- tests/fixtures/iot/KP200(US)_3.0_1.0.3.json | 10 +- tests/fixtures/iot/KP303(UK)_1.0_1.0.3.json | 14 +- tests/fixtures/iot/KP303(US)_2.0_1.0.3.json | 14 +- tests/fixtures/iot/KP303(US)_2.0_1.0.9.json | 12 +- tests/fixtures/iot/KP400(US)_1.0_1.0.10.json | 10 +- tests/fixtures/iot/KP400(US)_2.0_1.0.6.json | 10 +- tests/fixtures/iot/KP400(US)_3.0_1.0.3.json | 8 +- tests/fixtures/iot/KP400(US)_3.0_1.0.4.json | 8 +- tests/fixtures/iot/KP401(US)_1.0_1.0.0.json | 2 +- tests/fixtures/iot/KP405(US)_1.0_1.0.5.json | 2 +- tests/fixtures/iot/KS200(US)_1.0_1.0.8.json | 2 +- tests/fixtures/iot/KS200M(US)_1.0_1.0.10.json | 2 +- tests/fixtures/iot/KS200M(US)_1.0_1.0.8.json | 2 +- tests/fixtures/iot/KS220(US)_1.0_1.0.13.json | 2 +- tests/fixtures/iot/KS220M(US)_1.0_1.0.4.json | 2 +- tests/fixtures/iot/KS230(US)_1.0_1.0.14.json | 2 +- tests/fixtures/iot/LB110(US)_1.0_1.8.11.json | 2 +- tests/fixtures/smart/EP25(US)_2.6_1.0.1.json | 33 +-- tests/fixtures/smart/EP25(US)_2.6_1.0.2.json | 33 +-- tests/fixtures/smart/EP40M(US)_1.0_1.1.0.json | 33 +-- tests/fixtures/smart/H100(EU)_1.0_1.2.3.json | 33 +-- tests/fixtures/smart/H100(EU)_1.0_1.5.10.json | 33 +-- tests/fixtures/smart/H100(EU)_1.0_1.5.5.json | 37 +-- .../fixtures/smart/HS200(US)_5.26_1.0.3.json | 33 +-- .../fixtures/smart/HS220(US)_3.26_1.0.1.json | 31 +-- tests/fixtures/smart/KH100(EU)_1.0_1.2.3.json | 33 +-- .../fixtures/smart/KH100(EU)_1.0_1.5.12.json | 33 +-- tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json | 35 +-- .../fixtures/smart/KP125M(US)_1.0_1.1.3.json | 37 +-- .../fixtures/smart/KP125M(US)_1.0_1.2.3.json | 33 +-- tests/fixtures/smart/KS205(US)_1.0_1.0.2.json | 33 +-- tests/fixtures/smart/KS205(US)_1.0_1.1.0.json | 33 +-- tests/fixtures/smart/KS225(US)_1.0_1.0.2.json | 33 +-- tests/fixtures/smart/KS225(US)_1.0_1.1.0.json | 33 +-- tests/fixtures/smart/KS240(US)_1.0_1.0.4.json | 33 +-- tests/fixtures/smart/KS240(US)_1.0_1.0.5.json | 41 ++-- tests/fixtures/smart/KS240(US)_1.0_1.0.7.json | 33 +-- tests/fixtures/smart/L510B(EU)_3.0_1.0.5.json | 33 +-- tests/fixtures/smart/L510E(US)_3.0_1.0.5.json | 33 +-- tests/fixtures/smart/L510E(US)_3.0_1.1.2.json | 33 +-- tests/fixtures/smart/L530E(EU)_3.0_1.0.6.json | 33 +-- tests/fixtures/smart/L530E(EU)_3.0_1.1.0.json | 33 +-- tests/fixtures/smart/L530E(EU)_3.0_1.1.6.json | 35 +-- tests/fixtures/smart/L530E(US)_2.0_1.1.0.json | 33 +-- tests/fixtures/smart/L630(EU)_1.0_1.1.2.json | 33 +-- .../smart/L900-10(EU)_1.0_1.0.17.json | 33 +-- .../smart/L900-10(US)_1.0_1.0.11.json | 31 +-- .../fixtures/smart/L900-5(EU)_1.0_1.0.17.json | 33 +-- .../fixtures/smart/L900-5(EU)_1.0_1.1.0.json | 33 +-- .../fixtures/smart/L920-5(EU)_1.0_1.0.7.json | 31 +-- .../fixtures/smart/L920-5(EU)_1.0_1.1.3.json | 33 +-- .../fixtures/smart/L920-5(US)_1.0_1.1.0.json | 33 +-- .../fixtures/smart/L920-5(US)_1.0_1.1.3.json | 33 +-- .../fixtures/smart/L930-5(US)_1.0_1.1.2.json | 33 +-- .../fixtures/smart/P100(US)_1.0.0_1.1.3.json | 29 +-- .../fixtures/smart/P100(US)_1.0.0_1.3.7.json | 33 +-- .../fixtures/smart/P100(US)_1.0.0_1.4.0.json | 31 +-- tests/fixtures/smart/P110(EU)_1.0_1.0.7.json | 29 +-- tests/fixtures/smart/P110(EU)_1.0_1.2.3.json | 33 +-- tests/fixtures/smart/P110(UK)_1.0_1.3.0.json | 33 +-- tests/fixtures/smart/P110M(AU)_1.0_1.2.3.json | 59 ++--- tests/fixtures/smart/P110M(EU)_1.0_1.2.3.json | 33 +-- tests/fixtures/smart/P115(EU)_1.0_1.2.3.json | 33 +-- tests/fixtures/smart/P115(US)_1.0_1.1.3.json | 33 +-- tests/fixtures/smart/P125M(US)_1.0_1.1.0.json | 33 +-- tests/fixtures/smart/P135(US)_1.0_1.0.5.json | 33 +-- tests/fixtures/smart/P300(EU)_1.0_1.0.13.json | 45 ++-- tests/fixtures/smart/P300(EU)_1.0_1.0.15.json | 33 +-- tests/fixtures/smart/P300(EU)_1.0_1.0.7.json | 51 ++-- tests/fixtures/smart/P304M(UK)_1.0_1.0.3.json | 33 +-- tests/fixtures/smart/S500D(US)_1.0_1.0.5.json | 33 +-- tests/fixtures/smart/S505(US)_1.0_1.0.2.json | 33 +-- tests/fixtures/smart/S505D(US)_1.0_1.1.0.json | 33 +-- tests/fixtures/smart/TP15(US)_1.0_1.0.3.json | 33 +-- tests/fixtures/smart/TP25(US)_1.0_1.0.2.json | 41 ++-- .../fixtures/smartcam/C210(EU)_2.0_1.4.2.json | 63 ++--- .../fixtures/smartcam/C210(EU)_2.0_1.4.3.json | 63 ++--- .../smartcam/C520WS(US)_1.0_1.2.8.json | 65 +++--- .../fixtures/smartcam/H200(EU)_1.0_1.3.2.json | 59 ++--- .../fixtures/smartcam/H200(US)_1.0_1.3.6.json | 61 ++--- tests/fixtures/smartcam/TC65_1.0_1.3.9.json | 63 ++--- tests/test_cli.py | 2 +- tests/test_devtools.py | 6 +- tests/test_readme_examples.py | 32 ++- 140 files changed, 1771 insertions(+), 1407 deletions(-) create mode 100644 devtools/update_fixtures.py diff --git a/devtools/dump_devinfo.py b/devtools/dump_devinfo.py index 7760b6cb..02aebae7 100644 --- a/devtools/dump_devinfo.py +++ b/devtools/dump_devinfo.py @@ -10,8 +10,6 @@ and finally execute a query to query all of them at once. from __future__ import annotations -import base64 -import collections.abc import dataclasses import json import logging @@ -19,6 +17,7 @@ import re import sys import traceback from collections import defaultdict, namedtuple +from collections.abc import Callable from pathlib import Path from pprint import pprint from typing import Any @@ -39,13 +38,20 @@ from kasa import ( ) from kasa.device_factory import get_protocol from kasa.deviceconfig import DeviceEncryptionType, DeviceFamily -from kasa.discover import DiscoveryResult +from kasa.discover import ( + NEW_DISCOVERY_REDACTORS, + DiscoveredRaw, + DiscoveryResult, +) from kasa.exceptions import SmartErrorCode from kasa.protocols import IotProtocol +from kasa.protocols.iotprotocol import REDACTORS as IOT_REDACTORS +from kasa.protocols.protocol import redact_data from kasa.protocols.smartcamprotocol import ( SmartCamProtocol, _ChildCameraProtocolWrapper, ) +from kasa.protocols.smartprotocol import REDACTORS as SMART_REDACTORS from kasa.protocols.smartprotocol import SmartProtocol, _ChildProtocolWrapper from kasa.smart import SmartChildDevice, SmartDevice from kasa.smartcam import SmartCamDevice @@ -63,6 +69,42 @@ ENCRYPT_TYPES = [encrypt_type.value for encrypt_type in DeviceEncryptionType] _LOGGER = logging.getLogger(__name__) +def _wrap_redactors(redactors: dict[str, Callable[[Any], Any] | None]): + """Wrap the redactors for dump_devinfo. + + Will replace all partial REDACT_ values with zeros. + If the data item is already scrubbed by dump_devinfo will leave as-is. + """ + + def _wrap(key: str) -> Any: + def _wrapped(redactor: Callable[[Any], Any] | None) -> Any | None: + if redactor is None: + return lambda x: "**SCRUBBED**" + + def _redact_to_zeros(x: Any) -> Any: + if isinstance(x, str) and "REDACT" in x: + return re.sub(r"\w", "0", x) + if isinstance(x, dict): + for k, v in x.items(): + x[k] = _redact_to_zeros(v) + return x + + def _scrub(x: Any) -> Any: + if key in {"ip", "local_ip"}: + return "127.0.0.123" + # Already scrubbed by dump_devinfo + if isinstance(x, str) and "SCRUBBED" in x: + return x + default = redactor(x) + return _redact_to_zeros(default) + + return _scrub + + return _wrapped(redactors[key]) + + return {key: _wrap(key) for key in redactors} + + @dataclasses.dataclass class SmartCall: """Class for smart and smartcam calls.""" @@ -74,115 +116,6 @@ class SmartCall: supports_multiple: bool = True -def scrub(res): - """Remove identifiers from the given dict.""" - keys_to_scrub = [ - "deviceId", - "fwId", - "hwId", - "oemId", - "mac", - "mic_mac", - "latitude_i", - "longitude_i", - "latitude", - "longitude", - "la", # lat on ks240 - "lo", # lon on ks240 - "owner", - "device_id", - "ip", - "ssid", - "hw_id", - "fw_id", - "oem_id", - "nickname", - "alias", - "bssid", - "channel", - "original_device_id", # for child devices on strips - "parent_device_id", # for hub children - "setup_code", # matter - "setup_payload", # matter - "mfi_setup_code", # mfi_ for homekit - "mfi_setup_id", - "mfi_token_token", - "mfi_token_uuid", - "dev_id", - "device_name", - "device_alias", - "connect_ssid", - "encrypt_info", - "local_ip", - "username", - # vacuum - "board_sn", - "custom_sn", - "location", - ] - - for k, v in res.items(): - if isinstance(v, collections.abc.Mapping): - if k == "encrypt_info": - if "data" in v: - v["data"] = "" - if "key" in v: - v["key"] = "" - else: - res[k] = scrub(res.get(k)) - elif ( - isinstance(v, list) - and len(v) > 0 - and isinstance(v[0], collections.abc.Mapping) - ): - res[k] = [scrub(vi) for vi in v] - else: - if k in keys_to_scrub: - if k in ["mac", "mic_mac"]: - # Some macs have : or - as a separator and others do not - if len(v) == 12: - v = f"{v[:6]}000000" - else: - delim = ":" if ":" in v else "-" - rest = delim.join( - format(s, "02x") for s in bytes.fromhex("000000") - ) - v = f"{v[:8]}{delim}{rest}" - elif k in ["latitude", "latitude_i", "longitude", "longitude_i"]: - v = 0 - elif k in ["ip", "local_ip"]: - v = "127.0.0.123" - elif k in ["ssid"]: - # Need a valid base64 value here - v = base64.b64encode(b"#MASKED_SSID#").decode() - elif k in ["nickname"]: - v = base64.b64encode(b"#MASKED_NAME#").decode() - elif k in [ - "alias", - "device_alias", - "device_name", - "username", - "location", - ]: - v = "#MASKED_NAME#" - elif isinstance(res[k], int): - v = 0 - elif k in ["map_data"]: # - v = "#SCRUBBED_MAPDATA#" - elif k in ["device_id", "dev_id"] and "SCRUBBED" in v: - pass # already scrubbed - elif k == ["device_id", "dev_id"] and len(v) > 40: - # retain the last two chars when scrubbing child ids - end = v[-2:] - v = re.sub(r"\w", "0", v) - v = v[:40] + end - else: - v = re.sub(r"\w", "0", v) - - res[k] = v - return res - - def default_to_regular(d): """Convert nested defaultdicts to regular ones. @@ -209,7 +142,7 @@ async def handle_device( for fixture_result in fixture_results: save_filename = Path(basedir) / fixture_result.folder / fixture_result.filename - pprint(scrub(fixture_result.data)) + pprint(fixture_result.data) if autosave: save = "y" else: @@ -325,6 +258,11 @@ async def cli( if debug: logging.basicConfig(level=logging.DEBUG) + raw_discovery = {} + + def capture_raw(discovered: DiscoveredRaw): + raw_discovery[discovered["meta"]["ip"]] = discovered["discovery_response"] + credentials = Credentials(username=username, password=password) if host is not None: if discovery_info: @@ -377,12 +315,16 @@ async def cli( credentials=credentials, port=port, discovery_timeout=discovery_timeout, + on_discovered_raw=capture_raw, ) + discovery_info = raw_discovery[device.host] + if decrypted_data := device._discovery_info.get("decrypted_data"): + discovery_info["decrypted_data"] = decrypted_data await handle_device( basedir, autosave, device.protocol, - discovery_info=device._discovery_info, + discovery_info=discovery_info, batch_size=batch_size, ) else: @@ -391,21 +333,28 @@ async def cli( f" {target}. Use --target to override." ) devices = await Discover.discover( - target=target, credentials=credentials, discovery_timeout=discovery_timeout + target=target, + credentials=credentials, + discovery_timeout=discovery_timeout, + on_discovered_raw=capture_raw, ) click.echo(f"Detected {len(devices)} devices") for dev in devices.values(): + discovery_info = raw_discovery[dev.host] + if decrypted_data := dev._discovery_info.get("decrypted_data"): + discovery_info["decrypted_data"] = decrypted_data + await handle_device( basedir, autosave, dev.protocol, - discovery_info=dev._discovery_info, + discovery_info=discovery_info, batch_size=batch_size, ) async def get_legacy_fixture( - protocol: IotProtocol, *, discovery_info: dict[str, Any] | None + protocol: IotProtocol, *, discovery_info: dict[str, dict[str, Any]] | None ) -> FixtureResult: """Get fixture for legacy IOT style protocol.""" items = [ @@ -475,11 +424,21 @@ async def get_legacy_fixture( _echo_error(f"Unable to query all successes at once: {ex}") finally: await protocol.close() + + final = redact_data(final, _wrap_redactors(IOT_REDACTORS)) + + # Scrub the child device ids + if children := final.get("system", {}).get("get_sysinfo", {}).get("children"): + for index, child in enumerate(children): + if "id" not in child: + _LOGGER.error("Could not find a device for the child device: %s", child) + else: + child["id"] = f"SCRUBBED_CHILD_DEVICE_ID_{index + 1}" + if discovery_info and not discovery_info.get("system"): - # Need to recreate a DiscoverResult here because we don't want the aliases - # in the fixture, we want the actual field names as returned by the device. - dr = DiscoveryResult.from_dict(discovery_info) - final["discovery_result"] = dr.to_dict() + final["discovery_result"] = redact_data( + discovery_info, _wrap_redactors(NEW_DISCOVERY_REDACTORS) + ) click.echo(f"Got {len(successes)} successes") click.echo(click.style("## device info file ##", bold=True)) @@ -867,7 +826,10 @@ def get_smart_child_fixture(response): async def get_smart_fixtures( - protocol: SmartProtocol, *, discovery_info: dict[str, Any] | None, batch_size: int + protocol: SmartProtocol, + *, + discovery_info: dict[str, dict[str, Any]] | None, + batch_size: int, ) -> list[FixtureResult]: """Get fixture for new TAPO style protocol.""" if isinstance(protocol, SmartCamProtocol): @@ -988,22 +950,24 @@ async def get_smart_fixtures( continue _LOGGER.error("Could not find a device for the child device: %s", child) - # Need to recreate a DiscoverResult here because we don't want the aliases - # in the fixture, we want the actual field names as returned by the device. + final = redact_data(final, _wrap_redactors(SMART_REDACTORS)) + discovery_result = None if discovery_info: - dr = DiscoveryResult.from_dict(discovery_info) # type: ignore - final["discovery_result"] = dr.to_dict() + final["discovery_result"] = redact_data( + discovery_info, _wrap_redactors(NEW_DISCOVERY_REDACTORS) + ) + discovery_result = discovery_info["result"] click.echo(f"Got {len(successes)} successes") click.echo(click.style("## device info file ##", bold=True)) if "get_device_info" in final: # smart protocol - model_info = SmartDevice._get_device_info(final, discovery_info) + model_info = SmartDevice._get_device_info(final, discovery_result) copy_folder = SMART_FOLDER else: # smart camera protocol - model_info = SmartCamDevice._get_device_info(final, discovery_info) + model_info = SmartCamDevice._get_device_info(final, discovery_result) copy_folder = SMARTCAM_FOLDER hw_version = model_info.hardware_version sw_version = model_info.firmware_version diff --git a/devtools/generate_supported.py b/devtools/generate_supported.py index 532c7e6a..7b4e9787 100755 --- a/devtools/generate_supported.py +++ b/devtools/generate_supported.py @@ -205,7 +205,7 @@ def _get_supported_devices( fixture_data = json.load(f) model_info = device_cls._get_device_info( - fixture_data, fixture_data.get("discovery_result") + fixture_data, fixture_data.get("discovery_result", {}).get("result") ) supported_type = DEVICE_TYPE_TO_PRODUCT_GROUP[model_info.device_type] diff --git a/devtools/update_fixtures.py b/devtools/update_fixtures.py new file mode 100644 index 00000000..13b9996e --- /dev/null +++ b/devtools/update_fixtures.py @@ -0,0 +1,128 @@ +"""Module to mass update fixture files.""" + +import json +import logging +from collections.abc import Callable +from pathlib import Path + +import asyncclick as click + +from devtools.dump_devinfo import _wrap_redactors +from kasa.discover import NEW_DISCOVERY_REDACTORS, redact_data +from kasa.protocols.iotprotocol import REDACTORS as IOT_REDACTORS +from kasa.protocols.smartprotocol import REDACTORS as SMART_REDACTORS + +FIXTURE_FOLDER = "tests/fixtures/" + +_LOGGER = logging.getLogger(__name__) + + +def update_fixtures(update_func: Callable[[dict], bool], *, dry_run: bool) -> None: + """Run the update function against the fixtures.""" + for file in Path(FIXTURE_FOLDER).glob("**/*.json"): + with file.open("r") as f: + fixture_data = json.load(f) + + if file.parent.name == "serialization": + continue + changed = update_func(fixture_data) + if changed: + click.echo(f"Will update {file.name}\n") + if changed and not dry_run: + with file.open("w") as f: + json.dump(fixture_data, f, sort_keys=True, indent=4) + f.write("\n") + + +def _discovery_result_update(info) -> bool: + """Update discovery_result to be the raw result and error_code.""" + if (disco_result := info.get("discovery_result")) and "result" not in disco_result: + info["discovery_result"] = { + "result": disco_result, + "error_code": 0, + } + return True + return False + + +def _child_device_id_update(info) -> bool: + """Update child device ids to be the scrubbed ids from dump_devinfo.""" + changed = False + if get_child_device_list := info.get("get_child_device_list"): + child_device_list = get_child_device_list["child_device_list"] + child_component_list = info["get_child_device_component_list"][ + "child_component_list" + ] + for index, child_device in enumerate(child_device_list): + child_component = child_component_list[index] + if "SCRUBBED" not in child_device["device_id"]: + dev_id = f"SCRUBBED_CHILD_DEVICE_ID_{index + 1}" + click.echo( + f"child_device_id{index}: {child_device['device_id']} -> {dev_id}" + ) + child_device["device_id"] = dev_id + child_component["device_id"] = dev_id + changed = True + + if children := info.get("system", {}).get("get_sysinfo", {}).get("children"): + for index, child_device in enumerate(children): + if "SCRUBBED" not in child_device["id"]: + dev_id = f"SCRUBBED_CHILD_DEVICE_ID_{index + 1}" + click.echo(f"child_device_id{index}: {child_device['id']} -> {dev_id}") + child_device["id"] = dev_id + changed = True + + return changed + + +def _diff_data(fullkey, data1, data2, diffs): + if isinstance(data1, dict): + for k, v in data1.items(): + _diff_data(fullkey + "/" + k, v, data2[k], diffs) + elif isinstance(data1, list): + for index, item in enumerate(data1): + _diff_data(fullkey + "/" + str(index), item, data2[index], diffs) + elif data1 != data2: + diffs[fullkey] = (data1, data2) + + +def _redactor_result_update(info) -> bool: + """Update fixtures with the output using the common redactors.""" + changed = False + + redactors = IOT_REDACTORS if "system" in info else SMART_REDACTORS + + for key, val in info.items(): + if not isinstance(val, dict): + continue + if key == "discovery_result": + info[key] = redact_data(val, _wrap_redactors(NEW_DISCOVERY_REDACTORS)) + else: + info[key] = redact_data(val, _wrap_redactors(redactors)) + diffs: dict[str, tuple[str, str]] = {} + _diff_data(key, val, info[key], diffs) + if diffs: + for k, v in diffs.items(): + click.echo(f"{k}: {v[0]} -> {v[1]}") + changed = True + + return changed + + +@click.option( + "--dry-run/--no-dry-run", + default=False, + is_flag=True, + type=bool, + help="Perform a dry run without saving.", +) +@click.command() +async def cli(dry_run: bool) -> None: + """Cli method fo rupdating fixtures.""" + update_fixtures(_discovery_result_update, dry_run=dry_run) + update_fixtures(_child_device_id_update, dry_run=dry_run) + update_fixtures(_redactor_result_update, dry_run=dry_run) + + +if __name__ == "__main__": + cli() diff --git a/kasa/discover.py b/kasa/discover.py index d88fcc09..b7c545a2 100755 --- a/kasa/discover.py +++ b/kasa/discover.py @@ -168,6 +168,12 @@ OnUnsupportedCallable = Callable[[UnsupportedDeviceError], Coroutine] OnConnectAttemptCallable = Callable[[ConnectAttempt, bool], None] DeviceDict = dict[str, Device] +DECRYPTED_REDACTORS: dict[str, Callable[[Any], Any] | None] = { + "connect_ssid": lambda x: "#MASKED_SSID#" if x else "", + "device_id": lambda x: "REDACTED_" + x[9::], + "owner": lambda x: "REDACTED_" + x[9::], +} + NEW_DISCOVERY_REDACTORS: dict[str, Callable[[Any], Any] | None] = { "device_id": lambda x: "REDACTED_" + x[9::], "device_name": lambda x: "#MASKED_NAME#" if x else "", @@ -177,6 +183,8 @@ NEW_DISCOVERY_REDACTORS: dict[str, Callable[[Any], Any] | None] = { "group_id": lambda x: "REDACTED_" + x[9::], "group_name": lambda x: "I01BU0tFRF9TU0lEIw==", "encrypt_info": lambda x: {**x, "key": "", "data": ""}, + "ip": lambda x: x, # don't redact but keep listed here for dump_devinfo + "decrypted_data": lambda x: redact_data(x, DECRYPTED_REDACTORS), } @@ -742,6 +750,7 @@ class Discover: @staticmethod def _decrypt_discovery_data(discovery_result: DiscoveryResult) -> None: + debug_enabled = _LOGGER.isEnabledFor(logging.DEBUG) if TYPE_CHECKING: assert discovery_result.encrypt_info assert _AesDiscoveryQuery.keypair @@ -757,7 +766,19 @@ class Discover: session = AesEncyptionSession(key, iv) decrypted_data = session.decrypt(encrypted_data) - discovery_result.decrypted_data = json_loads(decrypted_data) + result = json_loads(decrypted_data) + if debug_enabled: + data = ( + redact_data(result, DECRYPTED_REDACTORS) + if Discover._redact_data + else result + ) + _LOGGER.debug( + "Decrypted encrypt_info for %s: %s", + discovery_result.ip, + pf(data), + ) + discovery_result.decrypted_data = result @staticmethod def _get_discovery_json(data: bytes, ip: str) -> dict: diff --git a/kasa/protocols/iotprotocol.py b/kasa/protocols/iotprotocol.py index 3bc6c454..b58e57ae 100755 --- a/kasa/protocols/iotprotocol.py +++ b/kasa/protocols/iotprotocol.py @@ -25,19 +25,35 @@ if TYPE_CHECKING: _LOGGER = logging.getLogger(__name__) + +def _mask_children(children: list[dict[str, Any]]) -> list[dict[str, Any]]: + def mask_child(child: dict[str, Any], index: int) -> dict[str, Any]: + result = { + **child, + "id": f"SCRUBBED_CHILD_DEVICE_ID_{index+1}", + } + # Will leave empty aliases as blank + if child.get("alias"): + result["alias"] = f"#MASKED_NAME# {index + 1}" + return result + + return [mask_child(child, index) for index, child in enumerate(children)] + + REDACTORS: dict[str, Callable[[Any], Any] | None] = { "latitude": lambda x: 0, "longitude": lambda x: 0, "latitude_i": lambda x: 0, "longitude_i": lambda x: 0, "deviceId": lambda x: "REDACTED_" + x[9::], - "id": lambda x: "REDACTED_" + x[9::], + "children": _mask_children, "alias": lambda x: "#MASKED_NAME#" if x else "", "mac": mask_mac, "mic_mac": mask_mac, "ssid": lambda x: "#MASKED_SSID#" if x else "", "oemId": lambda x: "REDACTED_" + x[9::], "username": lambda _: "user@example.com", # cnCloud + "hwId": lambda x: "REDACTED_" + x[9::], } diff --git a/kasa/protocols/protocol.py b/kasa/protocols/protocol.py index 211a7b5a..fb09b882 100755 --- a/kasa/protocols/protocol.py +++ b/kasa/protocols/protocol.py @@ -66,6 +66,8 @@ def redact_data(data: _T, redactors: dict[str, Callable[[Any], Any] | None]) -> def mask_mac(mac: str) -> str: """Return mac address with last two octects blanked.""" + if len(mac) == 12: + return f"{mac[:6]}000000" delim = ":" if ":" in mac else "-" rest = delim.join(format(s, "02x") for s in bytes.fromhex("000000")) return f"{mac[:8]}{delim}{rest}" diff --git a/kasa/protocols/smartprotocol.py b/kasa/protocols/smartprotocol.py index 80e76ca6..0e092547 100644 --- a/kasa/protocols/smartprotocol.py +++ b/kasa/protocols/smartprotocol.py @@ -9,6 +9,7 @@ from __future__ import annotations import asyncio import base64 import logging +import re import time import uuid from collections.abc import Callable @@ -45,15 +46,27 @@ REDACTORS: dict[str, Callable[[Any], Any] | None] = { "original_device_id": lambda x: "REDACTED_" + x[9::], # Strip children "nickname": lambda x: "I01BU0tFRF9OQU1FIw==" if x else "", "mac": mask_mac, - "ssid": lambda x: "I01BU0tFRF9TU0lEIw=" if x else "", + "ssid": lambda x: "I01BU0tFRF9TU0lEIw==" if x else "", "bssid": lambda _: "000000000000", + "channel": lambda _: 0, "oem_id": lambda x: "REDACTED_" + x[9::], - "setup_code": None, # matter - "setup_payload": None, # matter - "mfi_setup_code": None, # mfi_ for homekit - "mfi_setup_id": None, - "mfi_token_token": None, - "mfi_token_uuid": None, + "setup_code": lambda x: re.sub(r"\w", "0", x), # matter + "setup_payload": lambda x: re.sub(r"\w", "0", x), # matter + "mfi_setup_code": lambda x: re.sub(r"\w", "0", x), # mfi_ for homekit + "mfi_setup_id": lambda x: re.sub(r"\w", "0", x), + "mfi_token_token": lambda x: re.sub(r"\w", "0", x), + "mfi_token_uuid": lambda x: re.sub(r"\w", "0", x), + "ip": lambda x: x, # don't redact but keep listed here for dump_devinfo + # smartcam + "dev_id": lambda x: "REDACTED_" + x[9::], + "device_name": lambda x: "#MASKED_NAME#" if x else "", + "device_alias": lambda x: "#MASKED_NAME#" if x else "", + "local_ip": lambda x: x, # don't redact but keep listed here for dump_devinfo + # robovac + "board_sn": lambda _: "000000000000", + "custom_sn": lambda _: "000000000000", + "location": lambda x: "#MASKED_NAME#" if x else "", + "map_data": lambda x: "#SCRUBBED_MAPDATA#" if x else "", } diff --git a/tests/device_fixtures.py b/tests/device_fixtures.py index b1756572..dd35cf8f 100644 --- a/tests/device_fixtures.py +++ b/tests/device_fixtures.py @@ -435,7 +435,7 @@ async def get_device_for_fixture( discovery_data = None if "discovery_result" in fixture_data.data: - discovery_data = fixture_data.data["discovery_result"] + discovery_data = fixture_data.data["discovery_result"]["result"] elif "system" in fixture_data.data: discovery_data = { "system": {"get_sysinfo": fixture_data.data["system"]["get_sysinfo"]} diff --git a/tests/discovery_fixtures.py b/tests/discovery_fixtures.py index 93921536..87541eff 100644 --- a/tests/discovery_fixtures.py +++ b/tests/discovery_fixtures.py @@ -139,7 +139,8 @@ smart_discovery = parametrize_discovery("smart discovery", protocol_filter={"SMA ) async def discovery_mock(request, mocker): """Mock discovery and patch protocol queries to use Fake protocols.""" - fixture_info: FixtureInfo = request.param + fi: FixtureInfo = request.param + fixture_info = FixtureInfo(fi.name, fi.protocol, copy.deepcopy(fi.data)) return patch_discovery({DISCOVERY_MOCK_IP: fixture_info}, mocker) @@ -170,8 +171,8 @@ def create_discovery_mock(ip: str, fixture_data: dict): ) if "discovery_result" in fixture_data: - discovery_data = {"result": fixture_data["discovery_result"].copy()} - discovery_result = fixture_data["discovery_result"] + discovery_data = fixture_data["discovery_result"].copy() + discovery_result = fixture_data["discovery_result"]["result"] device_type = discovery_result["device_type"] encrypt_type = discovery_result["mgt_encrypt_schm"].get( "encrypt_type", discovery_result.get("encrypt_info", {}).get("sym_schm") @@ -305,7 +306,7 @@ def discovery_data(request, mocker): mocker.patch("kasa.IotProtocol.query", return_value=fixture_data) mocker.patch("kasa.SmartProtocol.query", return_value=fixture_data) if "discovery_result" in fixture_data: - return {"result": fixture_data["discovery_result"]} + return fixture_data["discovery_result"].copy() else: return {"system": {"get_sysinfo": fixture_data["system"]["get_sysinfo"]}} diff --git a/tests/fixtures/iot/EP10(US)_1.0_1.0.2.json b/tests/fixtures/iot/EP10(US)_1.0_1.0.2.json index e40543d6..11cafb87 100644 --- a/tests/fixtures/iot/EP10(US)_1.0_1.0.2.json +++ b/tests/fixtures/iot/EP10(US)_1.0_1.0.2.json @@ -2,7 +2,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "167 lamp", + "alias": "#MASKED_NAME#", "dev_name": "Smart Wi-Fi Plug Mini", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/EP40(US)_1.0_1.0.2.json b/tests/fixtures/iot/EP40(US)_1.0_1.0.2.json index 238265a2..5be97e87 100644 --- a/tests/fixtures/iot/EP40(US)_1.0_1.0.2.json +++ b/tests/fixtures/iot/EP40(US)_1.0_1.0.2.json @@ -1,12 +1,12 @@ { "system": { "get_sysinfo": { - "alias": "TP-LINK_Smart Plug_004F", + "alias": "#MASKED_NAME#", "child_num": 2, "children": [ { - "alias": "Zombie", - "id": "8006231E1499BAC4D4BC7EFCD4B075181E6393F200", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -14,8 +14,8 @@ "state": 0 }, { - "alias": "Magic", - "id": "8006231E1499BAC4D4BC7EFCD4B075181E6393F201", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, diff --git a/tests/fixtures/iot/ES20M(US)_1.0_1.0.11.json b/tests/fixtures/iot/ES20M(US)_1.0_1.0.11.json index 99ecdaa5..6d15034f 100644 --- a/tests/fixtures/iot/ES20M(US)_1.0_1.0.11.json +++ b/tests/fixtures/iot/ES20M(US)_1.0_1.0.11.json @@ -11,7 +11,7 @@ "stopConnect": 0, "tcspInfo": "", "tcspStatus": 1, - "username": "#MASKED_NAME#" + "username": "user@example.com" }, "get_intl_fw_list": { "err_code": 0, diff --git a/tests/fixtures/iot/ES20M(US)_1.0_1.0.8.json b/tests/fixtures/iot/ES20M(US)_1.0_1.0.8.json index bb316b83..e28301d5 100644 --- a/tests/fixtures/iot/ES20M(US)_1.0_1.0.8.json +++ b/tests/fixtures/iot/ES20M(US)_1.0_1.0.8.json @@ -78,7 +78,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Test ES20M", + "alias": "#MASKED_NAME#", "brightness": 35, "dev_name": "Wi-Fi Smart Dimmer with sensor", "deviceId": "0000000000000000000000000000000000000000", diff --git a/tests/fixtures/iot/HS100(UK)_4.1_1.1.0.json b/tests/fixtures/iot/HS100(UK)_4.1_1.1.0.json index 6e33fd7d..324e193a 100644 --- a/tests/fixtures/iot/HS100(UK)_4.1_1.1.0.json +++ b/tests/fixtures/iot/HS100(UK)_4.1_1.1.0.json @@ -1,18 +1,21 @@ { "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "HS100(UK)", - "device_type": "IOT.SMARTPLUGSWITCH", - "factory_default": true, - "hw_ver": "4.1", - "ip": "127.0.0.123", - "mac": "CC-32-E5-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false - }, - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "HS100(UK)", + "device_type": "IOT.SMARTPLUGSWITCH", + "factory_default": true, + "hw_ver": "4.1", + "ip": "127.0.0.123", + "mac": "CC-32-E5-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false + }, + "owner": "00000000000000000000000000000000" + } }, "system": { "get_sysinfo": { diff --git a/tests/fixtures/iot/HS100(US)_1.0_1.2.5.json b/tests/fixtures/iot/HS100(US)_1.0_1.2.5.json index 1bbe29d4..1f2cad62 100644 --- a/tests/fixtures/iot/HS100(US)_1.0_1.2.5.json +++ b/tests/fixtures/iot/HS100(US)_1.0_1.2.5.json @@ -18,7 +18,7 @@ "system": { "get_sysinfo": { "active_mode": "schedule", - "alias": "Unused 3", + "alias": "#MASKED_NAME#", "dev_name": "Wi-Fi Smart Plug", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/HS100(US)_2.0_1.5.6.json b/tests/fixtures/iot/HS100(US)_2.0_1.5.6.json index 03dd42d5..f73d6233 100644 --- a/tests/fixtures/iot/HS100(US)_2.0_1.5.6.json +++ b/tests/fixtures/iot/HS100(US)_2.0_1.5.6.json @@ -20,7 +20,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "3D Printer", + "alias": "#MASKED_NAME#", "dev_name": "Smart Wi-Fi Plug", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/HS103(US)_1.0_1.5.7.json b/tests/fixtures/iot/HS103(US)_1.0_1.5.7.json index e5928c3d..ec388dd3 100644 --- a/tests/fixtures/iot/HS103(US)_1.0_1.5.7.json +++ b/tests/fixtures/iot/HS103(US)_1.0_1.5.7.json @@ -20,7 +20,7 @@ "system": { "get_sysinfo": { "active_mode": "schedule", - "alias": "Night lite", + "alias": "#MASKED_NAME#", "dev_name": "Smart Wi-Fi Plug Lite", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/HS103(US)_2.1_1.1.2.json b/tests/fixtures/iot/HS103(US)_2.1_1.1.2.json index 664845f6..a9064ac7 100644 --- a/tests/fixtures/iot/HS103(US)_2.1_1.1.2.json +++ b/tests/fixtures/iot/HS103(US)_2.1_1.1.2.json @@ -18,7 +18,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Corner", + "alias": "#MASKED_NAME#", "dev_name": "Smart Wi-Fi Plug Lite", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/HS103(US)_2.1_1.1.4.json b/tests/fixtures/iot/HS103(US)_2.1_1.1.4.json index 819c5bdd..cf7cb935 100644 --- a/tests/fixtures/iot/HS103(US)_2.1_1.1.4.json +++ b/tests/fixtures/iot/HS103(US)_2.1_1.1.4.json @@ -2,7 +2,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Plug", + "alias": "#MASKED_NAME#", "dev_name": "Smart Wi-Fi Plug Lite", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/HS105(US)_1.0_1.5.6.json b/tests/fixtures/iot/HS105(US)_1.0_1.5.6.json index 79691004..a84c0f49 100644 --- a/tests/fixtures/iot/HS105(US)_1.0_1.5.6.json +++ b/tests/fixtures/iot/HS105(US)_1.0_1.5.6.json @@ -20,7 +20,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Unused 1", + "alias": "#MASKED_NAME#", "dev_name": "Smart Wi-Fi Plug Mini", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/HS107(US)_1.0_1.0.8.json b/tests/fixtures/iot/HS107(US)_1.0_1.0.8.json index 046a89e9..ddc61ef8 100644 --- a/tests/fixtures/iot/HS107(US)_1.0_1.0.8.json +++ b/tests/fixtures/iot/HS107(US)_1.0_1.0.8.json @@ -17,12 +17,12 @@ }, "system": { "get_sysinfo": { - "alias": "TP-LINK_Smart Plug_D310", + "alias": "#MASKED_NAME#", "child_num": 2, "children": [ { - "alias": "Garage Charger 1", - "id": "00", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -30,8 +30,8 @@ "state": 0 }, { - "alias": "Garage Charger 2", - "id": "01", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, @@ -46,7 +46,7 @@ "hw_ver": "1.0", "latitude_i": 0, "led_off": 0, - "longitude_i": -0, + "longitude_i": 0, "mac": "00:00:00:00:00:00", "mic_type": "IOT.SMARTPLUGSWITCH", "model": "HS107(US)", diff --git a/tests/fixtures/iot/HS110(EU)_1.0_1.2.5.json b/tests/fixtures/iot/HS110(EU)_1.0_1.2.5.json index 99cba288..e75b18bc 100644 --- a/tests/fixtures/iot/HS110(EU)_1.0_1.2.5.json +++ b/tests/fixtures/iot/HS110(EU)_1.0_1.2.5.json @@ -11,7 +11,7 @@ "system": { "get_sysinfo": { "active_mode": "schedule", - "alias": "Bedroom Lamp Plug", + "alias": "#MASKED_NAME#", "dev_name": "Wi-Fi Smart Plug With Energy Monitoring", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/HS110(US)_1.0_1.2.6.json b/tests/fixtures/iot/HS110(US)_1.0_1.2.6.json index 5e285e72..cf5ac065 100644 --- a/tests/fixtures/iot/HS110(US)_1.0_1.2.6.json +++ b/tests/fixtures/iot/HS110(US)_1.0_1.2.6.json @@ -11,7 +11,7 @@ "system": { "get_sysinfo": { "active_mode": "schedule", - "alias": "Home Google WiFi HS110", + "alias": "#MASKED_NAME#", "dev_name": "Wi-Fi Smart Plug With Energy Monitoring", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/HS200(US)_2.0_1.5.7.json b/tests/fixtures/iot/HS200(US)_2.0_1.5.7.json index 2fbcc65c..31e4a5f9 100644 --- a/tests/fixtures/iot/HS200(US)_2.0_1.5.7.json +++ b/tests/fixtures/iot/HS200(US)_2.0_1.5.7.json @@ -20,7 +20,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Master Bedroom Fan", + "alias": "#MASKED_NAME#", "dev_name": "Smart Wi-Fi Light Switch", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/HS200(US)_5.0_1.0.2.json b/tests/fixtures/iot/HS200(US)_5.0_1.0.2.json index fc09e6f5..44370f2e 100644 --- a/tests/fixtures/iot/HS200(US)_5.0_1.0.2.json +++ b/tests/fixtures/iot/HS200(US)_5.0_1.0.2.json @@ -2,7 +2,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "House Fan", + "alias": "#MASKED_NAME#", "dev_name": "Smart Wi-Fi Light Switch", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/HS210(US)_1.0_1.5.8.json b/tests/fixtures/iot/HS210(US)_1.0_1.5.8.json index ced3e891..b286c53f 100644 --- a/tests/fixtures/iot/HS210(US)_1.0_1.5.8.json +++ b/tests/fixtures/iot/HS210(US)_1.0_1.5.8.json @@ -21,7 +21,7 @@ "get_sysinfo": { "abnormal_detect": 1, "active_mode": "none", - "alias": "Garage Light", + "alias": "#MASKED_NAME#", "dev_name": "Smart Wi-Fi 3-Way Light Switch", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/HS220(US)_1.0_1.5.7.json b/tests/fixtures/iot/HS220(US)_1.0_1.5.7.json index eef806fb..3826d198 100644 --- a/tests/fixtures/iot/HS220(US)_1.0_1.5.7.json +++ b/tests/fixtures/iot/HS220(US)_1.0_1.5.7.json @@ -28,7 +28,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Living Room Dimmer Switch", + "alias": "#MASKED_NAME#", "brightness": 25, "dev_name": "Smart Wi-Fi Dimmer", "deviceId": "000000000000000000000000000000000000000", @@ -38,9 +38,9 @@ "hwId": "00000000000000000000000000000000", "hw_ver": "1.0", "icon_hash": "", - "latitude_i": 11.6210, + "latitude_i": 0, "led_off": 0, - "longitude_i": 42.2074, + "longitude_i": 0, "mac": "00:00:00:00:00:00", "mic_type": "IOT.SMARTPLUGSWITCH", "model": "HS220(US)", diff --git a/tests/fixtures/iot/HS220(US)_2.0_1.0.3.json b/tests/fixtures/iot/HS220(US)_2.0_1.0.3.json index 61e3d84e..d7d0a5a2 100644 --- a/tests/fixtures/iot/HS220(US)_2.0_1.0.3.json +++ b/tests/fixtures/iot/HS220(US)_2.0_1.0.3.json @@ -17,7 +17,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Living Room Dimmer Switch", + "alias": "#MASKED_NAME#", "brightness": 100, "dev_name": "Wi-Fi Smart Dimmer", "deviceId": "0000000000000000000000000000000000000000", diff --git a/tests/fixtures/iot/HS300(US)_1.0_1.0.10.json b/tests/fixtures/iot/HS300(US)_1.0_1.0.10.json index a6d34957..0fc22a39 100644 --- a/tests/fixtures/iot/HS300(US)_1.0_1.0.10.json +++ b/tests/fixtures/iot/HS300(US)_1.0_1.0.10.json @@ -22,12 +22,12 @@ }, "system": { "get_sysinfo": { - "alias": "TP-LINK_Power Strip_DAE1", + "alias": "#MASKED_NAME#", "child_num": 6, "children": [ { - "alias": "Office Monitor 1", - "id": "00", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -35,8 +35,8 @@ "state": 0 }, { - "alias": "Office Monitor 2", - "id": "01", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, @@ -44,8 +44,8 @@ "state": 0 }, { - "alias": "Office Monitor 3", - "id": "02", + "alias": "#MASKED_NAME# 3", + "id": "SCRUBBED_CHILD_DEVICE_ID_3", "next_action": { "type": -1 }, @@ -53,8 +53,8 @@ "state": 0 }, { - "alias": "Office Laptop Dock", - "id": "03", + "alias": "#MASKED_NAME# 4", + "id": "SCRUBBED_CHILD_DEVICE_ID_4", "next_action": { "type": -1 }, @@ -62,8 +62,8 @@ "state": 0 }, { - "alias": "Office Desk Light", - "id": "04", + "alias": "#MASKED_NAME# 5", + "id": "SCRUBBED_CHILD_DEVICE_ID_5", "next_action": { "type": -1 }, @@ -71,8 +71,8 @@ "state": 0 }, { - "alias": "Laptop", - "id": "05", + "alias": "#MASKED_NAME# 6", + "id": "SCRUBBED_CHILD_DEVICE_ID_6", "next_action": { "type": -1 }, @@ -87,7 +87,7 @@ "hw_ver": "1.0", "latitude_i": 0, "led_off": 0, - "longitude_i": -0, + "longitude_i": 0, "mac": "00:00:00:00:00:00", "mic_type": "IOT.SMARTPLUGSWITCH", "model": "HS300(US)", diff --git a/tests/fixtures/iot/HS300(US)_1.0_1.0.21.json b/tests/fixtures/iot/HS300(US)_1.0_1.0.21.json index 388fadf3..a174027c 100644 --- a/tests/fixtures/iot/HS300(US)_1.0_1.0.21.json +++ b/tests/fixtures/iot/HS300(US)_1.0_1.0.21.json @@ -10,12 +10,12 @@ }, "system": { "get_sysinfo": { - "alias": "TP-LINK_Power Strip_2CA9", + "alias": "#MASKED_NAME#", "child_num": 6, "children": [ { - "alias": "Home CameraPC", - "id": "800623145DFF1AA096363EFD161C2E661A9D8DED00", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -23,8 +23,8 @@ "state": 1 }, { - "alias": "Home Firewalla", - "id": "800623145DFF1AA096363EFD161C2E661A9D8DED01", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, @@ -32,8 +32,8 @@ "state": 1 }, { - "alias": "Home Cox modem", - "id": "800623145DFF1AA096363EFD161C2E661A9D8DED02", + "alias": "#MASKED_NAME# 3", + "id": "SCRUBBED_CHILD_DEVICE_ID_3", "next_action": { "type": -1 }, @@ -41,8 +41,8 @@ "state": 1 }, { - "alias": "Home rpi3-2", - "id": "800623145DFF1AA096363EFD161C2E661A9D8DED03", + "alias": "#MASKED_NAME# 4", + "id": "SCRUBBED_CHILD_DEVICE_ID_4", "next_action": { "type": -1 }, @@ -50,8 +50,8 @@ "state": 1 }, { - "alias": "Home Camera Switch", - "id": "800623145DFF1AA096363EFD161C2E661A9D8DED05", + "alias": "#MASKED_NAME# 5", + "id": "SCRUBBED_CHILD_DEVICE_ID_5", "next_action": { "type": -1 }, @@ -59,8 +59,8 @@ "state": 1 }, { - "alias": "Home Network Switch", - "id": "800623145DFF1AA096363EFD161C2E661A9D8DED04", + "alias": "#MASKED_NAME# 6", + "id": "SCRUBBED_CHILD_DEVICE_ID_6", "next_action": { "type": -1 }, diff --git a/tests/fixtures/iot/HS300(US)_2.0_1.0.12.json b/tests/fixtures/iot/HS300(US)_2.0_1.0.12.json index bdab432e..bca72089 100644 --- a/tests/fixtures/iot/HS300(US)_2.0_1.0.12.json +++ b/tests/fixtures/iot/HS300(US)_2.0_1.0.12.json @@ -15,8 +15,8 @@ "child_num": 6, "children": [ { - "alias": "#MASKED_NAME#", - "id": "8006A0F1D01120C3F93794F7AACACDBE1EAD246D00", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -24,8 +24,8 @@ "state": 1 }, { - "alias": "#MASKED_NAME#", - "id": "8006A0F1D01120C3F93794F7AACACDBE1EAD246D01", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, @@ -33,8 +33,8 @@ "state": 1 }, { - "alias": "#MASKED_NAME#", - "id": "8006A0F1D01120C3F93794F7AACACDBE1EAD246D02", + "alias": "#MASKED_NAME# 3", + "id": "SCRUBBED_CHILD_DEVICE_ID_3", "next_action": { "type": -1 }, @@ -42,8 +42,8 @@ "state": 1 }, { - "alias": "#MASKED_NAME#", - "id": "8006A0F1D01120C3F93794F7AACACDBE1EAD246D03", + "alias": "#MASKED_NAME# 4", + "id": "SCRUBBED_CHILD_DEVICE_ID_4", "next_action": { "type": -1 }, @@ -51,8 +51,8 @@ "state": 1 }, { - "alias": "#MASKED_NAME#", - "id": "8006A0F1D01120C3F93794F7AACACDBE1EAD246D04", + "alias": "#MASKED_NAME# 5", + "id": "SCRUBBED_CHILD_DEVICE_ID_5", "next_action": { "type": -1 }, @@ -60,8 +60,8 @@ "state": 1 }, { - "alias": "#MASKED_NAME#", - "id": "8006A0F1D01120C3F93794F7AACACDBE1EAD246D05", + "alias": "#MASKED_NAME# 6", + "id": "SCRUBBED_CHILD_DEVICE_ID_6", "next_action": { "type": -1 }, diff --git a/tests/fixtures/iot/HS300(US)_2.0_1.0.3.json b/tests/fixtures/iot/HS300(US)_2.0_1.0.3.json index 3b99cf36..8a5b22c4 100644 --- a/tests/fixtures/iot/HS300(US)_2.0_1.0.3.json +++ b/tests/fixtures/iot/HS300(US)_2.0_1.0.3.json @@ -11,12 +11,12 @@ }, "system": { "get_sysinfo": { - "alias": "TP-LINK_Power Strip_5C33", + "alias": "#MASKED_NAME#", "child_num": 6, "children": [ { - "alias": "Plug 1", - "id": "8006AF35494E7DB13DDE9B8F40BF2E001E77031900", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -24,8 +24,8 @@ "state": 0 }, { - "alias": "Plug 2", - "id": "8006AF35494E7DB13DDE9B8F40BF2E001E77031901", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, @@ -33,8 +33,8 @@ "state": 0 }, { - "alias": "Plug 3", - "id": "8006AF35494E7DB13DDE9B8F40BF2E001E77031902", + "alias": "#MASKED_NAME# 3", + "id": "SCRUBBED_CHILD_DEVICE_ID_3", "next_action": { "type": -1 }, @@ -42,8 +42,8 @@ "state": 0 }, { - "alias": "Plug 4", - "id": "8006AF35494E7DB13DDE9B8F40BF2E001E77031903", + "alias": "#MASKED_NAME# 4", + "id": "SCRUBBED_CHILD_DEVICE_ID_4", "next_action": { "type": -1 }, @@ -51,8 +51,8 @@ "state": 0 }, { - "alias": "Plug 5", - "id": "8006AF35494E7DB13DDE9B8F40BF2E001E77031904", + "alias": "#MASKED_NAME# 5", + "id": "SCRUBBED_CHILD_DEVICE_ID_5", "next_action": { "type": -1 }, @@ -60,8 +60,8 @@ "state": 0 }, { - "alias": "Plug 6", - "id": "8006AF35494E7DB13DDE9B8F40BF2E001E77031905", + "alias": "#MASKED_NAME# 6", + "id": "SCRUBBED_CHILD_DEVICE_ID_6", "next_action": { "type": -1 }, diff --git a/tests/fixtures/iot/KL110(US)_1.0_1.8.11.json b/tests/fixtures/iot/KL110(US)_1.0_1.8.11.json index 94c38858..89b623bd 100644 --- a/tests/fixtures/iot/KL110(US)_1.0_1.8.11.json +++ b/tests/fixtures/iot/KL110(US)_1.0_1.8.11.json @@ -21,7 +21,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Bulb3", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL120(US)_1.0_1.8.11.json b/tests/fixtures/iot/KL120(US)_1.0_1.8.11.json index 1d8e1fce..0bbc9886 100644 --- a/tests/fixtures/iot/KL120(US)_1.0_1.8.11.json +++ b/tests/fixtures/iot/KL120(US)_1.0_1.8.11.json @@ -19,7 +19,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Home Family Room Table", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL120(US)_1.0_1.8.6.json b/tests/fixtures/iot/KL120(US)_1.0_1.8.6.json index c251f2fa..50bd202e 100644 --- a/tests/fixtures/iot/KL120(US)_1.0_1.8.6.json +++ b/tests/fixtures/iot/KL120(US)_1.0_1.8.6.json @@ -34,11 +34,11 @@ }, "description": "Smart Wi-Fi LED Bulb with Tunable White Light", "dev_state": "normal", - "deviceId": "801200814AD69370AC59DE5501319C051AF409C3", + "deviceId": "0000000000000000000000000000000000000000", "disco_ver": "1.0", "err_code": 0, "heapsize": 290784, - "hwId": "111E35908497A05512E259BB76801E10", + "hwId": "00000000000000000000000000000000", "hw_ver": "1.0", "is_color": 0, "is_dimmable": 1, @@ -52,10 +52,10 @@ "on_off": 1, "saturation": 0 }, - "mic_mac": "D80D17150474", + "mic_mac": "D80D17000000", "mic_type": "IOT.SMARTBULB", "model": "KL120(US)", - "oemId": "1210657CD7FBDC72895644388EEFAE8B", + "oemId": "00000000000000000000000000000000", "preferred_state": [ { "brightness": 100, diff --git a/tests/fixtures/iot/KL125(US)_1.20_1.0.5.json b/tests/fixtures/iot/KL125(US)_1.20_1.0.5.json index 1fca6924..aedcb1f6 100644 --- a/tests/fixtures/iot/KL125(US)_1.20_1.0.5.json +++ b/tests/fixtures/iot/KL125(US)_1.20_1.0.5.json @@ -20,7 +20,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "kasa-bc01", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL125(US)_2.0_1.0.7.json b/tests/fixtures/iot/KL125(US)_2.0_1.0.7.json index b7fa640b..9d19ca57 100644 --- a/tests/fixtures/iot/KL125(US)_2.0_1.0.7.json +++ b/tests/fixtures/iot/KL125(US)_2.0_1.0.7.json @@ -22,7 +22,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Test bulb 6", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL130(EU)_1.0_1.8.8.json b/tests/fixtures/iot/KL130(EU)_1.0_1.8.8.json index f15e3602..ce303462 100644 --- a/tests/fixtures/iot/KL130(EU)_1.0_1.8.8.json +++ b/tests/fixtures/iot/KL130(EU)_1.0_1.8.8.json @@ -11,7 +11,7 @@ "stopConnect": 0, "tcspInfo": "", "tcspStatus": 1, - "username": "#MASKED_NAME#" + "username": "user@example.com" }, "get_intl_fw_list": { "err_code": 0, diff --git a/tests/fixtures/iot/KL130(US)_1.0_1.8.11.json b/tests/fixtures/iot/KL130(US)_1.0_1.8.11.json index 3ee4cb2e..d9eaaca1 100644 --- a/tests/fixtures/iot/KL130(US)_1.0_1.8.11.json +++ b/tests/fixtures/iot/KL130(US)_1.0_1.8.11.json @@ -21,7 +21,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Bulb2", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL135(US)_1.0_1.0.15.json b/tests/fixtures/iot/KL135(US)_1.0_1.0.15.json index b6670a7a..38a8805d 100644 --- a/tests/fixtures/iot/KL135(US)_1.0_1.0.15.json +++ b/tests/fixtures/iot/KL135(US)_1.0_1.0.15.json @@ -11,7 +11,7 @@ "stopConnect": 0, "tcspInfo": "", "tcspStatus": 1, - "username": "#MASKED_NAME#" + "username": "user@example.com" }, "get_intl_fw_list": { "err_code": 0, diff --git a/tests/fixtures/iot/KL135(US)_1.0_1.0.6.json b/tests/fixtures/iot/KL135(US)_1.0_1.0.6.json index dc0ef45a..be34f9c5 100644 --- a/tests/fixtures/iot/KL135(US)_1.0_1.0.6.json +++ b/tests/fixtures/iot/KL135(US)_1.0_1.0.6.json @@ -20,7 +20,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "KL135 Bulb", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL400L5(US)_1.0_1.0.5.json b/tests/fixtures/iot/KL400L5(US)_1.0_1.0.5.json index 64adf555..1bcd088b 100644 --- a/tests/fixtures/iot/KL400L5(US)_1.0_1.0.5.json +++ b/tests/fixtures/iot/KL400L5(US)_1.0_1.0.5.json @@ -10,7 +10,7 @@ "get_sysinfo": { "LEF": 0, "active_mode": "none", - "alias": "Kl400", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL400L5(US)_1.0_1.0.8.json b/tests/fixtures/iot/KL400L5(US)_1.0_1.0.8.json index a737cd2a..6a15c16c 100644 --- a/tests/fixtures/iot/KL400L5(US)_1.0_1.0.8.json +++ b/tests/fixtures/iot/KL400L5(US)_1.0_1.0.8.json @@ -10,7 +10,7 @@ "get_sysinfo": { "LEF": 0, "active_mode": "none", - "alias": "Kl400", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL420L5(US)_1.0_1.0.2.json b/tests/fixtures/iot/KL420L5(US)_1.0_1.0.2.json index 0d19e794..2d16adba 100644 --- a/tests/fixtures/iot/KL420L5(US)_1.0_1.0.2.json +++ b/tests/fixtures/iot/KL420L5(US)_1.0_1.0.2.json @@ -10,7 +10,7 @@ "get_sysinfo": { "LEF": 1, "active_mode": "none", - "alias": "Kl420 test", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL430(UN)_2.0_1.0.8.json b/tests/fixtures/iot/KL430(UN)_2.0_1.0.8.json index a956575b..8a924c19 100644 --- a/tests/fixtures/iot/KL430(UN)_2.0_1.0.8.json +++ b/tests/fixtures/iot/KL430(UN)_2.0_1.0.8.json @@ -10,7 +10,7 @@ "get_sysinfo": { "LEF": 1, "active_mode": "none", - "alias": "Bedroom light strip", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL430(US)_1.0_1.0.10.json b/tests/fixtures/iot/KL430(US)_1.0_1.0.10.json index 9b6d8413..5bda5762 100644 --- a/tests/fixtures/iot/KL430(US)_1.0_1.0.10.json +++ b/tests/fixtures/iot/KL430(US)_1.0_1.0.10.json @@ -23,7 +23,7 @@ "system": { "get_sysinfo": { "active_mode": "schedule", - "alias": "Bedroom Lightstrip", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL430(US)_2.0_1.0.11.json b/tests/fixtures/iot/KL430(US)_2.0_1.0.11.json index f39c5519..380250ff 100644 --- a/tests/fixtures/iot/KL430(US)_2.0_1.0.11.json +++ b/tests/fixtures/iot/KL430(US)_2.0_1.0.11.json @@ -11,7 +11,7 @@ "stopConnect": 0, "tcspInfo": "", "tcspStatus": 1, - "username": "#MASKED_NAME#" + "username": "user@example.com" }, "get_intl_fw_list": { "err_code": 0, diff --git a/tests/fixtures/iot/KL430(US)_2.0_1.0.8.json b/tests/fixtures/iot/KL430(US)_2.0_1.0.8.json index e69a9dc1..c5cf550b 100644 --- a/tests/fixtures/iot/KL430(US)_2.0_1.0.8.json +++ b/tests/fixtures/iot/KL430(US)_2.0_1.0.8.json @@ -10,7 +10,7 @@ "get_sysinfo": { "LEF": 1, "active_mode": "none", - "alias": "89 strip", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL430(US)_2.0_1.0.9.json b/tests/fixtures/iot/KL430(US)_2.0_1.0.9.json index d5f2eafb..2d9f7535 100644 --- a/tests/fixtures/iot/KL430(US)_2.0_1.0.9.json +++ b/tests/fixtures/iot/KL430(US)_2.0_1.0.9.json @@ -10,7 +10,7 @@ "get_sysinfo": { "LEF": 1, "active_mode": "none", - "alias": "kl430 updated", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL50(US)_1.0_1.1.13.json b/tests/fixtures/iot/KL50(US)_1.0_1.1.13.json index f3e43c9a..6e30c136 100644 --- a/tests/fixtures/iot/KL50(US)_1.0_1.1.13.json +++ b/tests/fixtures/iot/KL50(US)_1.0_1.1.13.json @@ -22,7 +22,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Kl50", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KL60(UN)_1.0_1.1.4.json b/tests/fixtures/iot/KL60(UN)_1.0_1.1.4.json index fa842b47..22dadaee 100644 --- a/tests/fixtures/iot/KL60(UN)_1.0_1.1.4.json +++ b/tests/fixtures/iot/KL60(UN)_1.0_1.1.4.json @@ -32,7 +32,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "TP-LINK_Smart Bulb_9179", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" @@ -60,7 +60,7 @@ "on_off": 0 }, "longitude_i": 0, - "mic_mac": "74DA88C89179", + "mic_mac": "74DA88000000", "mic_type": "IOT.SMARTBULB", "model": "KL60(UN)", "oemId": "00000000000000000000000000000000", diff --git a/tests/fixtures/iot/KL60(US)_1.0_1.1.13.json b/tests/fixtures/iot/KL60(US)_1.0_1.1.13.json index e52cb85c..6834d925 100644 --- a/tests/fixtures/iot/KL60(US)_1.0_1.1.13.json +++ b/tests/fixtures/iot/KL60(US)_1.0_1.1.13.json @@ -22,7 +22,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Gold fil", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/iot/KP100(US)_3.0_1.0.1.json b/tests/fixtures/iot/KP100(US)_3.0_1.0.1.json index fb62654b..46e9ec4e 100644 --- a/tests/fixtures/iot/KP100(US)_3.0_1.0.1.json +++ b/tests/fixtures/iot/KP100(US)_3.0_1.0.1.json @@ -2,7 +2,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Kasa", + "alias": "#MASKED_NAME#", "dev_name": "Smart Wi-Fi Plug Mini", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/KP105(UK)_1.0_1.0.5.json b/tests/fixtures/iot/KP105(UK)_1.0_1.0.5.json index ce194375..91e310d3 100644 --- a/tests/fixtures/iot/KP105(UK)_1.0_1.0.5.json +++ b/tests/fixtures/iot/KP105(UK)_1.0_1.0.5.json @@ -11,7 +11,7 @@ "stopConnect": 0, "tcspInfo": "", "tcspStatus": 1, - "username": "#MASKED_NAME#" + "username": "user@example.com" }, "get_intl_fw_list": { "err_code": -7, diff --git a/tests/fixtures/iot/KP115(US)_1.0_1.0.17.json b/tests/fixtures/iot/KP115(US)_1.0_1.0.17.json index afb5a5fe..fb5efac8 100644 --- a/tests/fixtures/iot/KP115(US)_1.0_1.0.17.json +++ b/tests/fixtures/iot/KP115(US)_1.0_1.0.17.json @@ -11,7 +11,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Test plug", + "alias": "#MASKED_NAME#", "dev_name": "Smart Wi-Fi Plug Mini", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/KP125(US)_1.0_1.0.6.json b/tests/fixtures/iot/KP125(US)_1.0_1.0.6.json index cb32e7c6..2bb0d21e 100644 --- a/tests/fixtures/iot/KP125(US)_1.0_1.0.6.json +++ b/tests/fixtures/iot/KP125(US)_1.0_1.0.6.json @@ -11,7 +11,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Test plug", + "alias": "#MASKED_NAME#", "dev_name": "Smart Wi-Fi Plug Mini", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/KP200(US)_3.0_1.0.3.json b/tests/fixtures/iot/KP200(US)_3.0_1.0.3.json index fef495d6..40a57fd5 100644 --- a/tests/fixtures/iot/KP200(US)_3.0_1.0.3.json +++ b/tests/fixtures/iot/KP200(US)_3.0_1.0.3.json @@ -1,12 +1,12 @@ { "system": { "get_sysinfo": { - "alias": "TP-LINK_Smart Plug_C2D6", + "alias": "#MASKED_NAME#", "child_num": 2, "children": [ { - "alias": "One ", - "id": "80066788DFFFD572D9F2E4A5A6847669213E039F00", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -14,8 +14,8 @@ "state": 1 }, { - "alias": "Two ", - "id": "80066788DFFFD572D9F2E4A5A6847669213E039F01", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, diff --git a/tests/fixtures/iot/KP303(UK)_1.0_1.0.3.json b/tests/fixtures/iot/KP303(UK)_1.0_1.0.3.json index d02d766b..b5c6a105 100644 --- a/tests/fixtures/iot/KP303(UK)_1.0_1.0.3.json +++ b/tests/fixtures/iot/KP303(UK)_1.0_1.0.3.json @@ -1,12 +1,12 @@ { "system": { "get_sysinfo": { - "alias": "Bedroom Power Strip", + "alias": "#MASKED_NAME#", "child_num": 3, "children": [ { - "alias": "Plug 1", - "id": "8006E9854025B67C3F9D99BA1E66223D1C9A8A7700", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -14,8 +14,8 @@ "state": 1 }, { - "alias": "Plug 2", - "id": "8006E9854025B67C3F9D99BA1E66223D1C9A8A7701", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, @@ -23,8 +23,8 @@ "state": 0 }, { - "alias": "Plug 3", - "id": "8006E9854025B67C3F9D99BA1E66223D1C9A8A7702", + "alias": "#MASKED_NAME# 3", + "id": "SCRUBBED_CHILD_DEVICE_ID_3", "next_action": { "type": -1 }, diff --git a/tests/fixtures/iot/KP303(US)_2.0_1.0.3.json b/tests/fixtures/iot/KP303(US)_2.0_1.0.3.json index 96c2f8c9..a9590557 100644 --- a/tests/fixtures/iot/KP303(US)_2.0_1.0.3.json +++ b/tests/fixtures/iot/KP303(US)_2.0_1.0.3.json @@ -1,12 +1,12 @@ { "system": { "get_sysinfo": { - "alias": "TP-LINK_Power Strip_BDF6", + "alias": "#MASKED_NAME#", "child_num": 3, "children": [ { - "alias": "Plug 1", - "id": "800681855E0E9AEF096F4891B3DC88C71E59F42E00", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -14,8 +14,8 @@ "state": 0 }, { - "alias": "Plug 2", - "id": "800681855E0E9AEF096F4891B3DC88C71E59F42E01", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, @@ -23,8 +23,8 @@ "state": 0 }, { - "alias": "Plug 3", - "id": "800681855E0E9AEF096F4891B3DC88C71E59F42E02", + "alias": "#MASKED_NAME# 3", + "id": "SCRUBBED_CHILD_DEVICE_ID_3", "next_action": { "type": -1 }, diff --git a/tests/fixtures/iot/KP303(US)_2.0_1.0.9.json b/tests/fixtures/iot/KP303(US)_2.0_1.0.9.json index d500ebb8..333df3f6 100644 --- a/tests/fixtures/iot/KP303(US)_2.0_1.0.9.json +++ b/tests/fixtures/iot/KP303(US)_2.0_1.0.9.json @@ -5,8 +5,8 @@ "child_num": 3, "children": [ { - "alias": "#MASKED_NAME#", - "id": "800639AA097730E58235162FCDA301CE1F038F9101", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -14,8 +14,8 @@ "state": 1 }, { - "alias": "#MASKED_NAME#", - "id": "800639AA097730E58235162FCDA301CE1F038F9102", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, @@ -23,8 +23,8 @@ "state": 0 }, { - "alias": "#MASKED_NAME#", - "id": "800639AA097730E58235162FCDA301CE1F038F9100", + "alias": "#MASKED_NAME# 3", + "id": "SCRUBBED_CHILD_DEVICE_ID_3", "next_action": { "type": -1 }, diff --git a/tests/fixtures/iot/KP400(US)_1.0_1.0.10.json b/tests/fixtures/iot/KP400(US)_1.0_1.0.10.json index afdb7bfc..cd09a434 100644 --- a/tests/fixtures/iot/KP400(US)_1.0_1.0.10.json +++ b/tests/fixtures/iot/KP400(US)_1.0_1.0.10.json @@ -17,12 +17,12 @@ }, "system": { "get_sysinfo": { - "alias": "TP-LINK_Smart Plug_2ECE", + "alias": "#MASKED_NAME#", "child_num": 2, "children": [ { - "alias": "Rope", - "id": "00", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "action": 1, "schd_sec": 69240, @@ -32,8 +32,8 @@ "state": 0 }, { - "alias": "Plug 2", - "id": "01", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, diff --git a/tests/fixtures/iot/KP400(US)_2.0_1.0.6.json b/tests/fixtures/iot/KP400(US)_2.0_1.0.6.json index 23cd22d1..3f838a91 100644 --- a/tests/fixtures/iot/KP400(US)_2.0_1.0.6.json +++ b/tests/fixtures/iot/KP400(US)_2.0_1.0.6.json @@ -1,12 +1,12 @@ { "system": { "get_sysinfo": { - "alias": "TP-LINK_Smart Plug_DC2A", + "alias": "#MASKED_NAME#", "child_num": 2, "children": [ { - "alias": "Anc ", - "id": "8006B8E953CC4149E2B13AA27E0D18EF1DCFBF3400", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -14,8 +14,8 @@ "state": 1 }, { - "alias": "Plug 2", - "id": "8006B8E953CC4149E2B13AA27E0D18EF1DCFBF3401", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, diff --git a/tests/fixtures/iot/KP400(US)_3.0_1.0.3.json b/tests/fixtures/iot/KP400(US)_3.0_1.0.3.json index e93eea8f..ec1c37f3 100644 --- a/tests/fixtures/iot/KP400(US)_3.0_1.0.3.json +++ b/tests/fixtures/iot/KP400(US)_3.0_1.0.3.json @@ -5,8 +5,8 @@ "child_num": 2, "children": [ { - "alias": "#MASKED_NAME#", - "id": "8006521377E30159055A751347B5A5E321A8D0A100", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -14,8 +14,8 @@ "state": 1 }, { - "alias": "#MASKED_NAME#", - "id": "8006521377E30159055A751347B5A5E321A8D0A101", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, diff --git a/tests/fixtures/iot/KP400(US)_3.0_1.0.4.json b/tests/fixtures/iot/KP400(US)_3.0_1.0.4.json index 18580f4e..5a60a400 100644 --- a/tests/fixtures/iot/KP400(US)_3.0_1.0.4.json +++ b/tests/fixtures/iot/KP400(US)_3.0_1.0.4.json @@ -5,8 +5,8 @@ "child_num": 2, "children": [ { - "alias": "#MASKED_NAME#", - "id": "8006521377E30159055A751347B5A5E321A8D0A100", + "alias": "#MASKED_NAME# 1", + "id": "SCRUBBED_CHILD_DEVICE_ID_1", "next_action": { "type": -1 }, @@ -14,8 +14,8 @@ "state": 0 }, { - "alias": "#MASKED_NAME#", - "id": "8006521377E30159055A751347B5A5E321A8D0A101", + "alias": "#MASKED_NAME# 2", + "id": "SCRUBBED_CHILD_DEVICE_ID_2", "next_action": { "type": -1 }, diff --git a/tests/fixtures/iot/KP401(US)_1.0_1.0.0.json b/tests/fixtures/iot/KP401(US)_1.0_1.0.0.json index 644c4e5f..f3006cf4 100644 --- a/tests/fixtures/iot/KP401(US)_1.0_1.0.0.json +++ b/tests/fixtures/iot/KP401(US)_1.0_1.0.0.json @@ -2,7 +2,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Kp401", + "alias": "#MASKED_NAME#", "dev_name": "Smart Outdoor Plug", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/KP405(US)_1.0_1.0.5.json b/tests/fixtures/iot/KP405(US)_1.0_1.0.5.json index ad6357f3..806bdc27 100644 --- a/tests/fixtures/iot/KP405(US)_1.0_1.0.5.json +++ b/tests/fixtures/iot/KP405(US)_1.0_1.0.5.json @@ -15,7 +15,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Porch Lights", + "alias": "#MASKED_NAME#", "brightness": 50, "dev_name": "Kasa Smart Wi-Fi Outdoor Plug-In Dimmer", "deviceId": "0000000000000000000000000000000000000000", diff --git a/tests/fixtures/iot/KS200(US)_1.0_1.0.8.json b/tests/fixtures/iot/KS200(US)_1.0_1.0.8.json index 58971dd0..4fc94890 100644 --- a/tests/fixtures/iot/KS200(US)_1.0_1.0.8.json +++ b/tests/fixtures/iot/KS200(US)_1.0_1.0.8.json @@ -11,7 +11,7 @@ "stopConnect": 0, "tcspInfo": "", "tcspStatus": 1, - "username": "#MASKED_NAME#" + "username": "user@example.com" }, "get_intl_fw_list": { "err_code": 0, diff --git a/tests/fixtures/iot/KS200M(US)_1.0_1.0.10.json b/tests/fixtures/iot/KS200M(US)_1.0_1.0.10.json index 24acdb97..f9498ae9 100644 --- a/tests/fixtures/iot/KS200M(US)_1.0_1.0.10.json +++ b/tests/fixtures/iot/KS200M(US)_1.0_1.0.10.json @@ -11,7 +11,7 @@ "stopConnect": 0, "tcspInfo": "", "tcspStatus": 1, - "username": "#MASKED_NAME#" + "username": "user@example.com" }, "get_intl_fw_list": { "err_code": 0, diff --git a/tests/fixtures/iot/KS200M(US)_1.0_1.0.8.json b/tests/fixtures/iot/KS200M(US)_1.0_1.0.8.json index 3806895b..719dab2e 100644 --- a/tests/fixtures/iot/KS200M(US)_1.0_1.0.8.json +++ b/tests/fixtures/iot/KS200M(US)_1.0_1.0.8.json @@ -66,7 +66,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Test KS200M", + "alias": "#MASKED_NAME#", "dev_name": "Smart Light Switch with PIR", "deviceId": "0000000000000000000000000000000000000000", "err_code": 0, diff --git a/tests/fixtures/iot/KS220(US)_1.0_1.0.13.json b/tests/fixtures/iot/KS220(US)_1.0_1.0.13.json index f5c8c1dd..debdd722 100644 --- a/tests/fixtures/iot/KS220(US)_1.0_1.0.13.json +++ b/tests/fixtures/iot/KS220(US)_1.0_1.0.13.json @@ -11,7 +11,7 @@ "stopConnect": 0, "tcspInfo": "", "tcspStatus": 1, - "username": "#MASKED_NAME#" + "username": "user@example.com" }, "get_intl_fw_list": { "err_code": 0, diff --git a/tests/fixtures/iot/KS220M(US)_1.0_1.0.4.json b/tests/fixtures/iot/KS220M(US)_1.0_1.0.4.json index 40da46fd..3dceb322 100644 --- a/tests/fixtures/iot/KS220M(US)_1.0_1.0.4.json +++ b/tests/fixtures/iot/KS220M(US)_1.0_1.0.4.json @@ -78,7 +78,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Garage Entryway Lights", + "alias": "#MASKED_NAME#", "brightness": 100, "dev_name": "Wi-Fi Smart Dimmer with sensor", "deviceId": "0000000000000000000000000000000000000000", diff --git a/tests/fixtures/iot/KS230(US)_1.0_1.0.14.json b/tests/fixtures/iot/KS230(US)_1.0_1.0.14.json index a9e529bc..8876a1af 100644 --- a/tests/fixtures/iot/KS230(US)_1.0_1.0.14.json +++ b/tests/fixtures/iot/KS230(US)_1.0_1.0.14.json @@ -14,7 +14,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "Test KS230", + "alias": "#MASKED_NAME#", "brightness": 60, "dc_state": 0, "dev_name": "Wi-Fi Smart 3-Way Dimmer", diff --git a/tests/fixtures/iot/LB110(US)_1.0_1.8.11.json b/tests/fixtures/iot/LB110(US)_1.0_1.8.11.json index ec49e91b..8df62f23 100644 --- a/tests/fixtures/iot/LB110(US)_1.0_1.8.11.json +++ b/tests/fixtures/iot/LB110(US)_1.0_1.8.11.json @@ -21,7 +21,7 @@ "system": { "get_sysinfo": { "active_mode": "none", - "alias": "TP-LINK_Smart Bulb_43EC", + "alias": "#MASKED_NAME#", "ctrl_protocols": { "name": "Linkie", "version": "1.0" diff --git a/tests/fixtures/smart/EP25(US)_2.6_1.0.1.json b/tests/fixtures/smart/EP25(US)_2.6_1.0.1.json index 61e12b25..e83c6221 100644 --- a/tests/fixtures/smart/EP25(US)_2.6_1.0.1.json +++ b/tests/fixtures/smart/EP25(US)_2.6_1.0.1.json @@ -84,21 +84,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "EP25(US)", - "device_type": "SMART.KASAPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "00-00-00-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "EP25(US)", + "device_type": "SMART.KASAPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "00-00-00-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/EP25(US)_2.6_1.0.2.json b/tests/fixtures/smart/EP25(US)_2.6_1.0.2.json index 2d3e2e5e..4aebbe0e 100644 --- a/tests/fixtures/smart/EP25(US)_2.6_1.0.2.json +++ b/tests/fixtures/smart/EP25(US)_2.6_1.0.2.json @@ -88,21 +88,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "EP25(US)", - "device_type": "SMART.KASAPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "3C-52-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "EP25(US)", + "device_type": "SMART.KASAPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "3C-52-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/EP40M(US)_1.0_1.1.0.json b/tests/fixtures/smart/EP40M(US)_1.0_1.1.0.json index 1126fad5..9eef29dc 100644 --- a/tests/fixtures/smart/EP40M(US)_1.0_1.1.0.json +++ b/tests/fixtures/smart/EP40M(US)_1.0_1.1.0.json @@ -379,21 +379,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "EP40M(US)", - "device_type": "SMART.KASAPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "F0-09-0D-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "matter", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "EP40M(US)", + "device_type": "SMART.KASAPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "F0-09-0D-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "matter", + "owner": "00000000000000000000000000000000" + } }, "get_auto_update_info": { "enable": true, diff --git a/tests/fixtures/smart/H100(EU)_1.0_1.2.3.json b/tests/fixtures/smart/H100(EU)_1.0_1.2.3.json index 4d4936c6..ba09016a 100644 --- a/tests/fixtures/smart/H100(EU)_1.0_1.2.3.json +++ b/tests/fixtures/smart/H100(EU)_1.0_1.2.3.json @@ -84,21 +84,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "H100(EU)", - "device_type": "SMART.TAPOHUB", - "factory_default": true, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "3C-52-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "H100(EU)", + "device_type": "SMART.TAPOHUB", + "factory_default": true, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "3C-52-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "" + } }, "get_auto_update_info": { "enable": true, diff --git a/tests/fixtures/smart/H100(EU)_1.0_1.5.10.json b/tests/fixtures/smart/H100(EU)_1.0_1.5.10.json index 021309c7..8173333a 100644 --- a/tests/fixtures/smart/H100(EU)_1.0_1.5.10.json +++ b/tests/fixtures/smart/H100(EU)_1.0_1.5.10.json @@ -96,21 +96,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "H100(EU)", - "device_type": "SMART.TAPOHUB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "3C-52-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "H100(EU)", + "device_type": "SMART.TAPOHUB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "3C-52-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_alarm_configure": { "duration": 10, diff --git a/tests/fixtures/smart/H100(EU)_1.0_1.5.5.json b/tests/fixtures/smart/H100(EU)_1.0_1.5.5.json index 639122bd..fadb35d2 100644 --- a/tests/fixtures/smart/H100(EU)_1.0_1.5.5.json +++ b/tests/fixtures/smart/H100(EU)_1.0_1.5.5.json @@ -92,21 +92,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "H100(EU)", - "device_type": "SMART.TAPOHUB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "3C-52-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "H100(EU)", + "device_type": "SMART.TAPOHUB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "3C-52-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_alarm_configure": { "duration": 10, @@ -195,7 +198,7 @@ "ver_code": 1 } ], - "device_id": "0000000000000000000000000000000000000000" + "device_id": "SCRUBBED_CHILD_DEVICE_ID_1" } ], "start_index": 0, @@ -213,7 +216,7 @@ "current_humidity_exception": -34, "current_temp": 22.2, "current_temp_exception": 0, - "device_id": "0000000000000000000000000000000000000000", + "device_id": "SCRUBBED_CHILD_DEVICE_ID_1", "fw_ver": "1.7.0 Build 230424 Rel.170332", "hw_id": "00000000000000000000000000000000", "hw_ver": "1.0", diff --git a/tests/fixtures/smart/HS200(US)_5.26_1.0.3.json b/tests/fixtures/smart/HS200(US)_5.26_1.0.3.json index e67435a9..f17269cc 100644 --- a/tests/fixtures/smart/HS200(US)_5.26_1.0.3.json +++ b/tests/fixtures/smart/HS200(US)_5.26_1.0.3.json @@ -80,21 +80,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "HS200(US)", - "device_type": "SMART.KASASWITCH", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "74-FE-CE-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "HS200(US)", + "device_type": "SMART.KASASWITCH", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "74-FE-CE-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/HS220(US)_3.26_1.0.1.json b/tests/fixtures/smart/HS220(US)_3.26_1.0.1.json index 63ec680b..99818984 100644 --- a/tests/fixtures/smart/HS220(US)_3.26_1.0.1.json +++ b/tests/fixtures/smart/HS220(US)_3.26_1.0.1.json @@ -100,20 +100,23 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "owner": "00000000000000000000000000000000", - "device_type": "SMART.KASASWITCH", - "device_model": "HS220(US)", - "ip": "127.0.0.123", - "mac": "24-2F-D0-00-00-00", - "is_support_iot_cloud": true, - "obd_src": "tplink", - "factory_default": false, - "mgt_encrypt_schm": { - "is_support_https": false, - "encrypt_type": "AES", - "http_port": 80, - "lv": 2 + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "HS220(US)", + "device_type": "SMART.KASASWITCH", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "24-2F-D0-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" } }, "get_antitheft_rules": { diff --git a/tests/fixtures/smart/KH100(EU)_1.0_1.2.3.json b/tests/fixtures/smart/KH100(EU)_1.0_1.2.3.json index 4ef13a07..0f24be14 100644 --- a/tests/fixtures/smart/KH100(EU)_1.0_1.2.3.json +++ b/tests/fixtures/smart/KH100(EU)_1.0_1.2.3.json @@ -84,21 +84,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "KH100(EU)", - "device_type": "SMART.KASAHUB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "A8-42-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KH100(EU)", + "device_type": "SMART.KASAHUB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "A8-42-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_alarm_configure": { "duration": 300, diff --git a/tests/fixtures/smart/KH100(EU)_1.0_1.5.12.json b/tests/fixtures/smart/KH100(EU)_1.0_1.5.12.json index 937fe36c..53684a58 100644 --- a/tests/fixtures/smart/KH100(EU)_1.0_1.5.12.json +++ b/tests/fixtures/smart/KH100(EU)_1.0_1.5.12.json @@ -88,21 +88,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "KH100(EU)", - "device_type": "SMART.KASAHUB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "A8-42-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KH100(EU)", + "device_type": "SMART.KASAHUB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "A8-42-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_alarm_configure": { "duration": 300, diff --git a/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json b/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json index 33e4cec6..c0eeb89b 100644 --- a/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json +++ b/tests/fixtures/smart/KH100(UK)_1.0_1.5.6.json @@ -1,4 +1,4 @@ - { +{ "component_nego": { "component_list": [ { @@ -88,21 +88,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "KH100(UK)", - "device_type": "SMART.KASAHUB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "F0-A7-31-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KH100(UK)", + "device_type": "SMART.KASAHUB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "F0-A7-31-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_alarm_configure": { "duration": 300, diff --git a/tests/fixtures/smart/KP125M(US)_1.0_1.1.3.json b/tests/fixtures/smart/KP125M(US)_1.0_1.1.3.json index c7b6ecb9..41a34cb3 100644 --- a/tests/fixtures/smart/KP125M(US)_1.0_1.1.3.json +++ b/tests/fixtures/smart/KP125M(US)_1.0_1.1.3.json @@ -84,21 +84,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "KP125M(US)", - "device_type": "SMART.KASAPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "00-00-00-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KP125M(US)", + "device_type": "SMART.KASAPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "00-00-00-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_current_power": { "current_power": 17 @@ -124,7 +127,7 @@ "longitude": 0, "mac": "00-00-00-00-00-00", "model": "KP125M", - "nickname": "IyNNQVNLRUROQU1FIyM=", + "nickname": "I01BU0tFRF9OQU1FIw==", "oem_id": "00000000000000000000000000000000", "on_time": 5332, "overheated": false, @@ -133,7 +136,7 @@ "rssi": -62, "signal_level": 2, "specs": "", - "ssid": "IyNNQVNLRUROQU1FIyM=", + "ssid": "I01BU0tFRF9TU0lEIw==", "time_diff": -360, "type": "SMART.KASAPLUG" }, diff --git a/tests/fixtures/smart/KP125M(US)_1.0_1.2.3.json b/tests/fixtures/smart/KP125M(US)_1.0_1.2.3.json index 710febeb..9878b65b 100644 --- a/tests/fixtures/smart/KP125M(US)_1.0_1.2.3.json +++ b/tests/fixtures/smart/KP125M(US)_1.0_1.2.3.json @@ -88,21 +88,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "KP125M(US)", - "device_type": "SMART.KASAPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "78-8C-B5-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KP125M(US)", + "device_type": "SMART.KASAPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "78-8C-B5-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/KS205(US)_1.0_1.0.2.json b/tests/fixtures/smart/KS205(US)_1.0_1.0.2.json index c94d4f2a..60611f33 100644 --- a/tests/fixtures/smart/KS205(US)_1.0_1.0.2.json +++ b/tests/fixtures/smart/KS205(US)_1.0_1.0.2.json @@ -80,21 +80,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "KS205(US)", - "device_type": "SMART.KASASWITCH", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "00-00-00-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KS205(US)", + "device_type": "SMART.KASASWITCH", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "00-00-00-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/KS205(US)_1.0_1.1.0.json b/tests/fixtures/smart/KS205(US)_1.0_1.1.0.json index f9ac5af9..9f7419ec 100644 --- a/tests/fixtures/smart/KS205(US)_1.0_1.1.0.json +++ b/tests/fixtures/smart/KS205(US)_1.0_1.1.0.json @@ -76,21 +76,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "KS205(US)", - "device_type": "SMART.KASASWITCH", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "40-ED-00-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KS205(US)", + "device_type": "SMART.KASASWITCH", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "40-ED-00-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/KS225(US)_1.0_1.0.2.json b/tests/fixtures/smart/KS225(US)_1.0_1.0.2.json index e6945cb8..1f2d9d2b 100644 --- a/tests/fixtures/smart/KS225(US)_1.0_1.0.2.json +++ b/tests/fixtures/smart/KS225(US)_1.0_1.0.2.json @@ -96,21 +96,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "KS225(US)", - "device_type": "SMART.KASASWITCH", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "00-00-00-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KS225(US)", + "device_type": "SMART.KASASWITCH", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "00-00-00-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/KS225(US)_1.0_1.1.0.json b/tests/fixtures/smart/KS225(US)_1.0_1.1.0.json index 798642d3..61ead929 100644 --- a/tests/fixtures/smart/KS225(US)_1.0_1.1.0.json +++ b/tests/fixtures/smart/KS225(US)_1.0_1.1.0.json @@ -96,21 +96,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "KS225(US)", - "device_type": "SMART.KASASWITCH", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "3C-52-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KS225(US)", + "device_type": "SMART.KASASWITCH", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "3C-52-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/KS240(US)_1.0_1.0.4.json b/tests/fixtures/smart/KS240(US)_1.0_1.0.4.json index 2775ee7c..15092b85 100644 --- a/tests/fixtures/smart/KS240(US)_1.0_1.0.4.json +++ b/tests/fixtures/smart/KS240(US)_1.0_1.0.4.json @@ -414,21 +414,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "KS240(US)", - "device_type": "SMART.KASASWITCH", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "F0-A7-31-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KS240(US)", + "device_type": "SMART.KASASWITCH", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "F0-A7-31-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_auto_update_info": { "enable": false, diff --git a/tests/fixtures/smart/KS240(US)_1.0_1.0.5.json b/tests/fixtures/smart/KS240(US)_1.0_1.0.5.json index 6d14f7bf..fb6c667d 100644 --- a/tests/fixtures/smart/KS240(US)_1.0_1.0.5.json +++ b/tests/fixtures/smart/KS240(US)_1.0_1.0.5.json @@ -104,21 +104,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "KS240(US)", - "device_type": "SMART.KASASWITCH", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "F0-A7-31-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KS240(US)", + "device_type": "SMART.KASASWITCH", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "F0-A7-31-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_auto_update_info": { "enable": false, @@ -206,7 +209,7 @@ "ver_code": 1 } ], - "device_id": "000000000000000000000000000000000000000001" + "device_id": "SCRUBBED_CHILD_DEVICE_ID_1" }, { "component_list": [ @@ -267,7 +270,7 @@ "ver_code": 1 } ], - "device_id": "000000000000000000000000000000000000000000" + "device_id": "SCRUBBED_CHILD_DEVICE_ID_2" } ], "start_index": 0, @@ -279,7 +282,7 @@ "avatar": "switch_ks240", "bind_count": 1, "category": "kasa.switch.outlet.sub-fan", - "device_id": "000000000000000000000000000000000000000000", + "device_id": "SCRUBBED_CHILD_DEVICE_ID_2", "device_on": true, "fan_sleep_mode_on": false, "fan_speed_level": 1, @@ -317,7 +320,7 @@ ], "type": "last_states" }, - "device_id": "000000000000000000000000000000000000000001", + "device_id": "SCRUBBED_CHILD_DEVICE_ID_1", "device_on": false, "fade_off_time": 1, "fade_on_time": 1, diff --git a/tests/fixtures/smart/KS240(US)_1.0_1.0.7.json b/tests/fixtures/smart/KS240(US)_1.0_1.0.7.json index a3f28309..4630a977 100644 --- a/tests/fixtures/smart/KS240(US)_1.0_1.0.7.json +++ b/tests/fixtures/smart/KS240(US)_1.0_1.0.7.json @@ -425,21 +425,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "KS240(US)", - "device_type": "SMART.KASASWITCH", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "F0-A7-31-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "KS240(US)", + "device_type": "SMART.KASASWITCH", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "F0-A7-31-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_auto_update_info": { "enable": true, diff --git a/tests/fixtures/smart/L510B(EU)_3.0_1.0.5.json b/tests/fixtures/smart/L510B(EU)_3.0_1.0.5.json index a53e93bb..f89dfc69 100644 --- a/tests/fixtures/smart/L510B(EU)_3.0_1.0.5.json +++ b/tests/fixtures/smart/L510B(EU)_3.0_1.0.5.json @@ -80,21 +80,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L510B(EU)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "5C-E9-31-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L510B(EU)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "5C-E9-31-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L510E(US)_3.0_1.0.5.json b/tests/fixtures/smart/L510E(US)_3.0_1.0.5.json index 9a51ea45..a81222e4 100644 --- a/tests/fixtures/smart/L510E(US)_3.0_1.0.5.json +++ b/tests/fixtures/smart/L510E(US)_3.0_1.0.5.json @@ -80,21 +80,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L510E(US)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "3C-52-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L510E(US)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "3C-52-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L510E(US)_3.0_1.1.2.json b/tests/fixtures/smart/L510E(US)_3.0_1.1.2.json index 055674d2..523d4992 100644 --- a/tests/fixtures/smart/L510E(US)_3.0_1.1.2.json +++ b/tests/fixtures/smart/L510E(US)_3.0_1.1.2.json @@ -88,21 +88,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L510E(US)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "3C-52-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L510E(US)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "3C-52-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L530E(EU)_3.0_1.0.6.json b/tests/fixtures/smart/L530E(EU)_3.0_1.0.6.json index 10b9d300..05c04522 100644 --- a/tests/fixtures/smart/L530E(EU)_3.0_1.0.6.json +++ b/tests/fixtures/smart/L530E(EU)_3.0_1.0.6.json @@ -100,21 +100,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L530E(EU)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "5C-E9-31-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L530E(EU)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "5C-E9-31-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L530E(EU)_3.0_1.1.0.json b/tests/fixtures/smart/L530E(EU)_3.0_1.1.0.json index b5b90d32..a32c0463 100644 --- a/tests/fixtures/smart/L530E(EU)_3.0_1.1.0.json +++ b/tests/fixtures/smart/L530E(EU)_3.0_1.1.0.json @@ -104,21 +104,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L530E(EU)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "5C-E9-31-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L530E(EU)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "5C-E9-31-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L530E(EU)_3.0_1.1.6.json b/tests/fixtures/smart/L530E(EU)_3.0_1.1.6.json index 0e0ad2fa..8da76d78 100644 --- a/tests/fixtures/smart/L530E(EU)_3.0_1.1.6.json +++ b/tests/fixtures/smart/L530E(EU)_3.0_1.1.6.json @@ -104,21 +104,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L530E(EU)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "5C-E9-31-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L530E(EU)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "5C-E9-31-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, @@ -175,7 +178,7 @@ "longitude": 0, "mac": "5C-E9-31-00-00-00", "model": "L530", - "nickname": "TGl2aW5nIFJvb20gQnVsYg==", + "nickname": "I01BU0tFRF9OQU1FIw==", "oem_id": "00000000000000000000000000000000", "overheated": false, "region": "Europe/Berlin", diff --git a/tests/fixtures/smart/L530E(US)_2.0_1.1.0.json b/tests/fixtures/smart/L530E(US)_2.0_1.1.0.json index 6dac1048..0c80d3a5 100644 --- a/tests/fixtures/smart/L530E(US)_2.0_1.1.0.json +++ b/tests/fixtures/smart/L530E(US)_2.0_1.1.0.json @@ -104,21 +104,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L530E(US)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "5C-62-8B-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L530E(US)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "5C-62-8B-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L630(EU)_1.0_1.1.2.json b/tests/fixtures/smart/L630(EU)_1.0_1.1.2.json index 4ca91c9b..3fb263be 100644 --- a/tests/fixtures/smart/L630(EU)_1.0_1.1.2.json +++ b/tests/fixtures/smart/L630(EU)_1.0_1.1.2.json @@ -104,21 +104,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L630(EU)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "40-AE-30-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L630(EU)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "40-AE-30-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L900-10(EU)_1.0_1.0.17.json b/tests/fixtures/smart/L900-10(EU)_1.0_1.0.17.json index 5d05bc94..816cf896 100644 --- a/tests/fixtures/smart/L900-10(EU)_1.0_1.0.17.json +++ b/tests/fixtures/smart/L900-10(EU)_1.0_1.0.17.json @@ -104,21 +104,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L900-10(EU)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "F0-A7-31-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L900-10(EU)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "F0-A7-31-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L900-10(US)_1.0_1.0.11.json b/tests/fixtures/smart/L900-10(US)_1.0_1.0.11.json index 8665c8f3..5c81fd32 100644 --- a/tests/fixtures/smart/L900-10(US)_1.0_1.0.11.json +++ b/tests/fixtures/smart/L900-10(US)_1.0_1.0.11.json @@ -100,20 +100,23 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L900-10(US)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "54-AF-97-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L900-10(US)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "54-AF-97-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L900-5(EU)_1.0_1.0.17.json b/tests/fixtures/smart/L900-5(EU)_1.0_1.0.17.json index a281f2ec..7c7ac420 100644 --- a/tests/fixtures/smart/L900-5(EU)_1.0_1.0.17.json +++ b/tests/fixtures/smart/L900-5(EU)_1.0_1.0.17.json @@ -104,21 +104,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L900-5(EU)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "A8-42-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L900-5(EU)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "A8-42-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L900-5(EU)_1.0_1.1.0.json b/tests/fixtures/smart/L900-5(EU)_1.0_1.1.0.json index 136d3a0f..98980a4c 100644 --- a/tests/fixtures/smart/L900-5(EU)_1.0_1.1.0.json +++ b/tests/fixtures/smart/L900-5(EU)_1.0_1.1.0.json @@ -108,21 +108,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L900-5(EU)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "A8-42-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L900-5(EU)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "A8-42-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L920-5(EU)_1.0_1.0.7.json b/tests/fixtures/smart/L920-5(EU)_1.0_1.0.7.json index a55707ae..3315b19b 100644 --- a/tests/fixtures/smart/L920-5(EU)_1.0_1.0.7.json +++ b/tests/fixtures/smart/L920-5(EU)_1.0_1.0.7.json @@ -104,20 +104,23 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L920-5(EU)", - "device_type": "SMART.TAPOBULB", - "factory_default": true, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "1C-61-B4-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false - }, - "obd_src": "tplink", - "owner": "" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L920-5(EU)", + "device_type": "SMART.TAPOBULB", + "factory_default": true, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "1C-61-B4-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false + }, + "obd_src": "tplink", + "owner": "" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L920-5(EU)_1.0_1.1.3.json b/tests/fixtures/smart/L920-5(EU)_1.0_1.1.3.json index 5f03b5b6..0f845bf3 100644 --- a/tests/fixtures/smart/L920-5(EU)_1.0_1.1.3.json +++ b/tests/fixtures/smart/L920-5(EU)_1.0_1.1.3.json @@ -116,21 +116,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L920-5(EU)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "B4-B0-24-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L920-5(EU)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "B4-B0-24-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L920-5(US)_1.0_1.1.0.json b/tests/fixtures/smart/L920-5(US)_1.0_1.1.0.json index 2ea0c69f..95e8f969 100644 --- a/tests/fixtures/smart/L920-5(US)_1.0_1.1.0.json +++ b/tests/fixtures/smart/L920-5(US)_1.0_1.1.0.json @@ -112,21 +112,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L920-5(US)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "00-00-00-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L920-5(US)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "00-00-00-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L920-5(US)_1.0_1.1.3.json b/tests/fixtures/smart/L920-5(US)_1.0_1.1.3.json index 5463944d..992f6399 100644 --- a/tests/fixtures/smart/L920-5(US)_1.0_1.1.3.json +++ b/tests/fixtures/smart/L920-5(US)_1.0_1.1.3.json @@ -116,21 +116,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L920-5(US)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "34-60-F9-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L920-5(US)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "34-60-F9-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/L930-5(US)_1.0_1.1.2.json b/tests/fixtures/smart/L930-5(US)_1.0_1.1.2.json index de7ae2c7..c374ebc5 100644 --- a/tests/fixtures/smart/L930-5(US)_1.0_1.1.2.json +++ b/tests/fixtures/smart/L930-5(US)_1.0_1.1.2.json @@ -124,21 +124,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "L930-5(US)", - "device_type": "SMART.TAPOBULB", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "3C-52-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "L930-5(US)", + "device_type": "SMART.TAPOBULB", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "3C-52-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/P100(US)_1.0.0_1.1.3.json b/tests/fixtures/smart/P100(US)_1.0.0_1.1.3.json index 337c6f2c..2ae738cd 100644 --- a/tests/fixtures/smart/P100(US)_1.0.0_1.1.3.json +++ b/tests/fixtures/smart/P100(US)_1.0.0_1.1.3.json @@ -56,18 +56,21 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P100", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "mac": "1C-3B-F3-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false - }, - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P100", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "mac": "1C-3B-F3-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false + }, + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, @@ -93,7 +96,7 @@ "hw_ver": "1.0.0", "ip": "127.0.0.123", "latitude": 0, - "location": "hallway", + "location": "#MASKED_NAME#", "longitude": 0, "mac": "1C-3B-F3-00-00-00", "model": "P100", diff --git a/tests/fixtures/smart/P100(US)_1.0.0_1.3.7.json b/tests/fixtures/smart/P100(US)_1.0.0_1.3.7.json index cdddc72e..5347d070 100644 --- a/tests/fixtures/smart/P100(US)_1.0.0_1.3.7.json +++ b/tests/fixtures/smart/P100(US)_1.0.0_1.3.7.json @@ -64,20 +64,23 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P100", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "CC-32-E5-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P100", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "CC-32-E5-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, @@ -108,7 +111,7 @@ "ip": "127.0.0.123", "lang": "en_US", "latitude": 0, - "location": "bedroom", + "location": "#MASKED_NAME#", "longitude": 0, "mac": "CC-32-E5-00-00-00", "model": "P100", diff --git a/tests/fixtures/smart/P100(US)_1.0.0_1.4.0.json b/tests/fixtures/smart/P100(US)_1.0.0_1.4.0.json index 5ec33343..ab75faf5 100644 --- a/tests/fixtures/smart/P100(US)_1.0.0_1.4.0.json +++ b/tests/fixtures/smart/P100(US)_1.0.0_1.4.0.json @@ -64,20 +64,23 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P100", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "74-DA-88-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P100", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "74-DA-88-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/P110(EU)_1.0_1.0.7.json b/tests/fixtures/smart/P110(EU)_1.0_1.0.7.json index 6332f259..dd7a0360 100644 --- a/tests/fixtures/smart/P110(EU)_1.0_1.0.7.json +++ b/tests/fixtures/smart/P110(EU)_1.0_1.0.7.json @@ -72,19 +72,22 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P110(EU)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "34-60-F9-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false - }, - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P110(EU)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "34-60-F9-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false + }, + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/P110(EU)_1.0_1.2.3.json b/tests/fixtures/smart/P110(EU)_1.0_1.2.3.json index 415e8ce6..62e580fc 100644 --- a/tests/fixtures/smart/P110(EU)_1.0_1.2.3.json +++ b/tests/fixtures/smart/P110(EU)_1.0_1.2.3.json @@ -80,21 +80,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P110(EU)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "48-22-54-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P110(EU)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "48-22-54-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/P110(UK)_1.0_1.3.0.json b/tests/fixtures/smart/P110(UK)_1.0_1.3.0.json index 339c5fb2..0c7f6e83 100644 --- a/tests/fixtures/smart/P110(UK)_1.0_1.3.0.json +++ b/tests/fixtures/smart/P110(UK)_1.0_1.3.0.json @@ -88,21 +88,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P110(UK)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "48-22-54-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P110(UK)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "48-22-54-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/P110M(AU)_1.0_1.2.3.json b/tests/fixtures/smart/P110M(AU)_1.0_1.2.3.json index efb88c85..2fea4379 100644 --- a/tests/fixtures/smart/P110M(AU)_1.0_1.2.3.json +++ b/tests/fixtures/smart/P110M(AU)_1.0_1.2.3.json @@ -96,21 +96,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P110M(AU)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "F0-09-0D-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P110M(AU)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "F0-09-0D-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_auto_off_config": { "delay_min": 120, @@ -124,19 +127,6 @@ "get_connect_cloud_state": { "status": 1 }, - "get_energy_usage": { - "today_runtime": 306, - "month_runtime": 12572, - "today_energy": 173, - "month_energy": 6110, - "local_time": "2024-11-22 21:03:25", - "electricity_charge": [ - 0, - 0, - 0 - ], - "current_power": 74116 - }, "get_current_power": { "current_power": 74 }, @@ -313,6 +303,19 @@ }, "type": "constant" }, + "get_energy_usage": { + "current_power": 74116, + "electricity_charge": [ + 0, + 0, + 0 + ], + "local_time": "2024-11-22 21:03:25", + "month_energy": 6110, + "month_runtime": 12572, + "today_energy": 173, + "today_runtime": 306 + }, "get_fw_download_state": { "auto_upgrade": false, "download_progress": 0, diff --git a/tests/fixtures/smart/P110M(EU)_1.0_1.2.3.json b/tests/fixtures/smart/P110M(EU)_1.0_1.2.3.json index d8453319..81174d7b 100644 --- a/tests/fixtures/smart/P110M(EU)_1.0_1.2.3.json +++ b/tests/fixtures/smart/P110M(EU)_1.0_1.2.3.json @@ -96,21 +96,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P110M(EU)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "F0-A7-31-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "matter", - "owner": "" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P110M(EU)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "F0-A7-31-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "matter", + "owner": "" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/P115(EU)_1.0_1.2.3.json b/tests/fixtures/smart/P115(EU)_1.0_1.2.3.json index 48cd46f2..33d7465c 100644 --- a/tests/fixtures/smart/P115(EU)_1.0_1.2.3.json +++ b/tests/fixtures/smart/P115(EU)_1.0_1.2.3.json @@ -80,21 +80,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P115(EU)", - "device_type": "SMART.TAPOPLUG", - "factory_default": true, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "A8-42-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P115(EU)", + "device_type": "SMART.TAPOPLUG", + "factory_default": true, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "A8-42-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/P115(US)_1.0_1.1.3.json b/tests/fixtures/smart/P115(US)_1.0_1.1.3.json index 70035368..151f7300 100644 --- a/tests/fixtures/smart/P115(US)_1.0_1.1.3.json +++ b/tests/fixtures/smart/P115(US)_1.0_1.1.3.json @@ -96,21 +96,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P115(US)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "B0-19-21-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P115(US)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "B0-19-21-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/P125M(US)_1.0_1.1.0.json b/tests/fixtures/smart/P125M(US)_1.0_1.1.0.json index 78e876d7..1e0cf7e2 100644 --- a/tests/fixtures/smart/P125M(US)_1.0_1.1.0.json +++ b/tests/fixtures/smart/P125M(US)_1.0_1.1.0.json @@ -80,21 +80,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P125M(US)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "48-22-54-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P125M(US)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "48-22-54-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/P135(US)_1.0_1.0.5.json b/tests/fixtures/smart/P135(US)_1.0_1.0.5.json index 9f6c3b03..f1099cc7 100644 --- a/tests/fixtures/smart/P135(US)_1.0_1.0.5.json +++ b/tests/fixtures/smart/P135(US)_1.0_1.0.5.json @@ -96,21 +96,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P135(US)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "F0-A7-31-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P135(US)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "F0-A7-31-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/P300(EU)_1.0_1.0.13.json b/tests/fixtures/smart/P300(EU)_1.0_1.0.13.json index 0d7d4a3b..73f76e83 100644 --- a/tests/fixtures/smart/P300(EU)_1.0_1.0.13.json +++ b/tests/fixtures/smart/P300(EU)_1.0_1.0.13.json @@ -84,21 +84,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P300(EU)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "78-8C-B5-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P300(EU)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "78-8C-B5-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_auto_update_info": { "enable": false, @@ -170,7 +173,7 @@ "ver_code": 1 } ], - "device_id": "000000000000000000000000000000000000000002" + "device_id": "SCRUBBED_CHILD_DEVICE_ID_1" }, { "component_list": [ @@ -235,7 +238,7 @@ "ver_code": 1 } ], - "device_id": "000000000000000000000000000000000000000001" + "device_id": "SCRUBBED_CHILD_DEVICE_ID_2" }, { "component_list": [ @@ -300,7 +303,7 @@ "ver_code": 1 } ], - "device_id": "000000000000000000000000000000000000000000" + "device_id": "SCRUBBED_CHILD_DEVICE_ID_3" } ], "start_index": 0, @@ -318,7 +321,7 @@ }, "type": "custom" }, - "device_id": "000000000000000000000000000000000000000002", + "device_id": "SCRUBBED_CHILD_DEVICE_ID_1", "device_on": false, "fw_id": "00000000000000000000000000000000", "fw_ver": "1.0.13 Build 230925 Rel.150200", @@ -347,7 +350,7 @@ "default_states": { "type": "last_states" }, - "device_id": "000000000000000000000000000000000000000001", + "device_id": "SCRUBBED_CHILD_DEVICE_ID_2", "device_on": false, "fw_id": "00000000000000000000000000000000", "fw_ver": "1.0.13 Build 230925 Rel.150200", @@ -379,7 +382,7 @@ }, "type": "custom" }, - "device_id": "000000000000000000000000000000000000000000", + "device_id": "SCRUBBED_CHILD_DEVICE_ID_3", "device_on": false, "fw_id": "00000000000000000000000000000000", "fw_ver": "1.0.13 Build 230925 Rel.150200", diff --git a/tests/fixtures/smart/P300(EU)_1.0_1.0.15.json b/tests/fixtures/smart/P300(EU)_1.0_1.0.15.json index dd40708e..e9d4b54f 100644 --- a/tests/fixtures/smart/P300(EU)_1.0_1.0.15.json +++ b/tests/fixtures/smart/P300(EU)_1.0_1.0.15.json @@ -495,21 +495,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P300(EU)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "78-8C-B5-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P300(EU)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "78-8C-B5-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_auto_update_info": { "enable": false, diff --git a/tests/fixtures/smart/P300(EU)_1.0_1.0.7.json b/tests/fixtures/smart/P300(EU)_1.0_1.0.7.json index 17df5ac5..eaa03a35 100644 --- a/tests/fixtures/smart/P300(EU)_1.0_1.0.7.json +++ b/tests/fixtures/smart/P300(EU)_1.0_1.0.7.json @@ -84,21 +84,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P300(EU)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "78-8C-B5-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P300(EU)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "78-8C-B5-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_auto_update_info": { "enable": true, @@ -170,7 +173,7 @@ "ver_code": 1 } ], - "device_id": "000000000000000000000000000000000000000001" + "device_id": "SCRUBBED_CHILD_DEVICE_ID_1" }, { "component_list": [ @@ -235,7 +238,7 @@ "ver_code": 1 } ], - "device_id": "000000000000000000000000000000000000000002" + "device_id": "SCRUBBED_CHILD_DEVICE_ID_2" }, { "component_list": [ @@ -300,7 +303,7 @@ "ver_code": 1 } ], - "device_id": "000000000000000000000000000000000000000003" + "device_id": "SCRUBBED_CHILD_DEVICE_ID_3" } ], "start_index": 0, @@ -315,7 +318,7 @@ "default_states": { "type": "last_states" }, - "device_id": "000000000000000000000000000000000000000001", + "device_id": "SCRUBBED_CHILD_DEVICE_ID_1", "device_on": true, "fw_id": "00000000000000000000000000000000", "fw_ver": "1.0.7 Build 220715 Rel.200458", @@ -329,7 +332,7 @@ "nickname": "I01BU0tFRF9OQU1FIw==", "oem_id": "00000000000000000000000000000000", "on_time": 366, - "original_device_id": "8022852468EC205A8178C7CBE81FC119213BC020", + "original_device_id": "0000000000000000000000000000000000000000", "overheat_status": "normal", "position": 1, "region": "Europe/Berlin", @@ -344,7 +347,7 @@ "default_states": { "type": "last_states" }, - "device_id": "000000000000000000000000000000000000000002", + "device_id": "SCRUBBED_CHILD_DEVICE_ID_2", "device_on": true, "fw_id": "00000000000000000000000000000000", "fw_ver": "1.0.7 Build 220715 Rel.200458", @@ -358,7 +361,7 @@ "nickname": "I01BU0tFRF9OQU1FIw==", "oem_id": "00000000000000000000000000000000", "on_time": 366, - "original_device_id": "8022852468EC205A8178C7CBE81FC119213BC020", + "original_device_id": "0000000000000000000000000000000000000000", "overheat_status": "normal", "position": 2, "region": "Europe/Berlin", @@ -373,7 +376,7 @@ "default_states": { "type": "last_states" }, - "device_id": "000000000000000000000000000000000000000003", + "device_id": "SCRUBBED_CHILD_DEVICE_ID_3", "device_on": true, "fw_id": "00000000000000000000000000000000", "fw_ver": "1.0.7 Build 220715 Rel.200458", @@ -387,7 +390,7 @@ "nickname": "I01BU0tFRF9OQU1FIw==", "oem_id": "00000000000000000000000000000000", "on_time": 366, - "original_device_id": "8022852468EC205A8178C7CBE81FC119213BC020", + "original_device_id": "0000000000000000000000000000000000000000", "overheat_status": "normal", "position": 3, "region": "Europe/Berlin", diff --git a/tests/fixtures/smart/P304M(UK)_1.0_1.0.3.json b/tests/fixtures/smart/P304M(UK)_1.0_1.0.3.json index 4e67f482..398977ad 100644 --- a/tests/fixtures/smart/P304M(UK)_1.0_1.0.3.json +++ b/tests/fixtures/smart/P304M(UK)_1.0_1.0.3.json @@ -1385,21 +1385,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "P304M(UK)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "A8-6E-84-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "P304M(UK)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "A8-6E-84-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_auto_update_info": { "enable": true, diff --git a/tests/fixtures/smart/S500D(US)_1.0_1.0.5.json b/tests/fixtures/smart/S500D(US)_1.0_1.0.5.json index a141e700..3e6ec48d 100644 --- a/tests/fixtures/smart/S500D(US)_1.0_1.0.5.json +++ b/tests/fixtures/smart/S500D(US)_1.0_1.0.5.json @@ -92,21 +92,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "S500D(US)", - "device_type": "SMART.TAPOSWITCH", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "48-22-54-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "S500D(US)", + "device_type": "SMART.TAPOSWITCH", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "48-22-54-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/S505(US)_1.0_1.0.2.json b/tests/fixtures/smart/S505(US)_1.0_1.0.2.json index c9c63cd7..340bd3a1 100644 --- a/tests/fixtures/smart/S505(US)_1.0_1.0.2.json +++ b/tests/fixtures/smart/S505(US)_1.0_1.0.2.json @@ -80,21 +80,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "S505(US)", - "device_type": "SMART.TAPOSWITCH", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "3C-52-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "S505(US)", + "device_type": "SMART.TAPOSWITCH", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "3C-52-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/S505D(US)_1.0_1.1.0.json b/tests/fixtures/smart/S505D(US)_1.0_1.1.0.json index 6adac986..0c990d75 100644 --- a/tests/fixtures/smart/S505D(US)_1.0_1.1.0.json +++ b/tests/fixtures/smart/S505D(US)_1.0_1.1.0.json @@ -100,21 +100,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "S505D(US)", - "device_type": "SMART.TAPOSWITCH", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "48-22-54-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "KLAP", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "matter", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "S505D(US)", + "device_type": "SMART.TAPOSWITCH", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "48-22-54-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "KLAP", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "matter", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/TP15(US)_1.0_1.0.3.json b/tests/fixtures/smart/TP15(US)_1.0_1.0.3.json index 404bfe2f..8d0964b3 100644 --- a/tests/fixtures/smart/TP15(US)_1.0_1.0.3.json +++ b/tests/fixtures/smart/TP15(US)_1.0_1.0.3.json @@ -76,21 +76,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "TP15(US)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "5C-62-8B-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "TP15(US)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "5C-62-8B-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_antitheft_rules": { "antitheft_rule_max_count": 1, diff --git a/tests/fixtures/smart/TP25(US)_1.0_1.0.2.json b/tests/fixtures/smart/TP25(US)_1.0_1.0.2.json index 1e3321f8..b9165414 100644 --- a/tests/fixtures/smart/TP25(US)_1.0_1.0.2.json +++ b/tests/fixtures/smart/TP25(US)_1.0_1.0.2.json @@ -84,21 +84,24 @@ ] }, "discovery_result": { - "device_id": "00000000000000000000000000000000", - "device_model": "TP25(US)", - "device_type": "SMART.TAPOPLUG", - "factory_default": false, - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "3C-52-A1-00-00-00", - "mgt_encrypt_schm": { - "encrypt_type": "AES", - "http_port": 80, - "is_support_https": false, - "lv": 2 - }, - "obd_src": "tplink", - "owner": "00000000000000000000000000000000" + "error_code": 0, + "result": { + "device_id": "00000000000000000000000000000000", + "device_model": "TP25(US)", + "device_type": "SMART.TAPOPLUG", + "factory_default": false, + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "3C-52-A1-00-00-00", + "mgt_encrypt_schm": { + "encrypt_type": "AES", + "http_port": 80, + "is_support_https": false, + "lv": 2 + }, + "obd_src": "tplink", + "owner": "00000000000000000000000000000000" + } }, "get_auto_update_info": { "enable": false, @@ -170,7 +173,7 @@ "ver_code": 1 } ], - "device_id": "000000000000000000000000000000000000000000" + "device_id": "SCRUBBED_CHILD_DEVICE_ID_1" }, { "component_list": [ @@ -235,7 +238,7 @@ "ver_code": 1 } ], - "device_id": "000000000000000000000000000000000000000001" + "device_id": "SCRUBBED_CHILD_DEVICE_ID_2" } ], "start_index": 0, @@ -250,7 +253,7 @@ "default_states": { "type": "last_states" }, - "device_id": "000000000000000000000000000000000000000000", + "device_id": "SCRUBBED_CHILD_DEVICE_ID_1", "device_on": false, "fw_id": "00000000000000000000000000000000", "fw_ver": "1.0.2 Build 230206 Rel.095245", @@ -279,7 +282,7 @@ "default_states": { "type": "last_states" }, - "device_id": "000000000000000000000000000000000000000001", + "device_id": "SCRUBBED_CHILD_DEVICE_ID_2", "device_on": true, "fw_id": "00000000000000000000000000000000", "fw_ver": "1.0.2 Build 230206 Rel.095245", diff --git a/tests/fixtures/smartcam/C210(EU)_2.0_1.4.2.json b/tests/fixtures/smartcam/C210(EU)_2.0_1.4.2.json index ba2e0010..609c46be 100644 --- a/tests/fixtures/smartcam/C210(EU)_2.0_1.4.2.json +++ b/tests/fixtures/smartcam/C210(EU)_2.0_1.4.2.json @@ -1,35 +1,38 @@ { "discovery_result": { - "decrypted_data": { - "connect_ssid": "0000000000", - "connect_type": "wireless", - "device_id": "0000000000000000000000000000000000000000", - "http_port": 443, - "last_alarm_time": "1729264456", - "last_alarm_type": "motion", - "owner": "00000000000000000000000000000000", - "sd_status": "offline" - }, - "device_id": "00000000000000000000000000000000", - "device_model": "C210", - "device_name": "#MASKED_NAME#", - "device_type": "SMART.IPCAMERA", - "encrypt_info": { - "data": "", - "key": "", - "sym_schm": "AES" - }, - "encrypt_type": [ - "3" - ], - "factory_default": false, - "firmware_version": "1.4.2 Build 240829 Rel.54953n", - "hardware_version": "2.0", - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "40-AE-30-00-00-00", - "mgt_encrypt_schm": { - "is_support_https": true + "error_code": 0, + "result": { + "decrypted_data": { + "connect_ssid": "#MASKED_SSID#", + "connect_type": "wireless", + "device_id": "0000000000000000000000000000000000000000", + "http_port": 443, + "last_alarm_time": "1729264456", + "last_alarm_type": "motion", + "owner": "00000000000000000000000000000000", + "sd_status": "offline" + }, + "device_id": "00000000000000000000000000000000", + "device_model": "C210", + "device_name": "#MASKED_NAME#", + "device_type": "SMART.IPCAMERA", + "encrypt_info": { + "data": "", + "key": "", + "sym_schm": "AES" + }, + "encrypt_type": [ + "3" + ], + "factory_default": false, + "firmware_version": "1.4.2 Build 240829 Rel.54953n", + "hardware_version": "2.0", + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "40-AE-30-00-00-00", + "mgt_encrypt_schm": { + "is_support_https": true + } } }, "getAlertConfig": { diff --git a/tests/fixtures/smartcam/C210(EU)_2.0_1.4.3.json b/tests/fixtures/smartcam/C210(EU)_2.0_1.4.3.json index a2f7666e..b6280118 100644 --- a/tests/fixtures/smartcam/C210(EU)_2.0_1.4.3.json +++ b/tests/fixtures/smartcam/C210(EU)_2.0_1.4.3.json @@ -1,35 +1,38 @@ { "discovery_result": { - "decrypted_data": { - "connect_ssid": "0000000000", - "connect_type": "wireless", - "device_id": "0000000000000000000000000000000000000000", - "http_port": 443, - "last_alarm_time": "0", - "last_alarm_type": "", - "owner": "00000000000000000000000000000000", - "sd_status": "offline" - }, - "device_id": "00000000000000000000000000000000", - "device_model": "C210", - "device_name": "#MASKED_NAME#", - "device_type": "SMART.IPCAMERA", - "encrypt_info": { - "data": "", - "key": "", - "sym_schm": "AES" - }, - "encrypt_type": [ - "3" - ], - "factory_default": false, - "firmware_version": "1.4.3 Build 241010 Rel.33858n", - "hardware_version": "2.0", - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "40-AE-30-00-00-00", - "mgt_encrypt_schm": { - "is_support_https": true + "error_code": 0, + "result": { + "decrypted_data": { + "connect_ssid": "#MASKED_SSID#", + "connect_type": "wireless", + "device_id": "0000000000000000000000000000000000000000", + "http_port": 443, + "last_alarm_time": "0", + "last_alarm_type": "", + "owner": "00000000000000000000000000000000", + "sd_status": "offline" + }, + "device_id": "00000000000000000000000000000000", + "device_model": "C210", + "device_name": "#MASKED_NAME#", + "device_type": "SMART.IPCAMERA", + "encrypt_info": { + "data": "", + "key": "", + "sym_schm": "AES" + }, + "encrypt_type": [ + "3" + ], + "factory_default": false, + "firmware_version": "1.4.3 Build 241010 Rel.33858n", + "hardware_version": "2.0", + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "40-AE-30-00-00-00", + "mgt_encrypt_schm": { + "is_support_https": true + } } }, "getAlertConfig": { diff --git a/tests/fixtures/smartcam/C520WS(US)_1.0_1.2.8.json b/tests/fixtures/smartcam/C520WS(US)_1.0_1.2.8.json index 072fea80..4f156070 100644 --- a/tests/fixtures/smartcam/C520WS(US)_1.0_1.2.8.json +++ b/tests/fixtures/smartcam/C520WS(US)_1.0_1.2.8.json @@ -1,36 +1,39 @@ { "discovery_result": { - "decrypted_data": { - "connect_ssid": "000 000000 0000000000", - "connect_type": "wireless", - "device_id": "0000000000000000000000000000000000000000", - "http_port": 443, - "last_alarm_time": "0", - "last_alarm_type": "", - "owner": "00000000000000000000000000000000", - "sd_status": "offline" - }, - "device_id": "00000000000000000000000000000000", - "device_model": "C520WS", - "device_name": "#MASKED_NAME#", - "device_type": "SMART.IPCAMERA", - "encrypt_info": { - "data": "", - "key": "", - "sym_schm": "AES" - }, - "encrypt_type": [ - "3" - ], - "factory_default": false, - "firmware_version": "1.2.8 Build 240606 Rel.39146n", - "hardware_version": "1.0", - "ip": "127.0.0.123", - "isResetWiFi": false, - "is_support_iot_cloud": true, - "mac": "F0-A7-31-00-00-00", - "mgt_encrypt_schm": { - "is_support_https": true + "error_code": 0, + "result": { + "decrypted_data": { + "connect_ssid": "#MASKED_SSID#", + "connect_type": "wireless", + "device_id": "0000000000000000000000000000000000000000", + "http_port": 443, + "last_alarm_time": "0", + "last_alarm_type": "", + "owner": "00000000000000000000000000000000", + "sd_status": "offline" + }, + "device_id": "00000000000000000000000000000000", + "device_model": "C520WS", + "device_name": "#MASKED_NAME#", + "device_type": "SMART.IPCAMERA", + "encrypt_info": { + "data": "", + "key": "", + "sym_schm": "AES" + }, + "encrypt_type": [ + "3" + ], + "factory_default": false, + "firmware_version": "1.2.8 Build 240606 Rel.39146n", + "hardware_version": "1.0", + "ip": "127.0.0.123", + "isResetWiFi": false, + "is_support_iot_cloud": true, + "mac": "F0-A7-31-00-00-00", + "mgt_encrypt_schm": { + "is_support_https": true + } } }, "getAlertConfig": { diff --git a/tests/fixtures/smartcam/H200(EU)_1.0_1.3.2.json b/tests/fixtures/smartcam/H200(EU)_1.0_1.3.2.json index 04bcc262..9ccaa7e0 100644 --- a/tests/fixtures/smartcam/H200(EU)_1.0_1.3.2.json +++ b/tests/fixtures/smartcam/H200(EU)_1.0_1.3.2.json @@ -1,33 +1,36 @@ { "discovery_result": { - "decrypted_data": { - "connect_ssid": "", - "connect_type": "wired", - "device_id": "0000000000000000000000000000000000000000", - "http_port": 443, - "owner": "00000000000000000000000000000000", - "sd_status": "offline" - }, - "device_id": "00000000000000000000000000000000", - "device_model": "H200", - "device_name": "#MASKED_NAME#", - "device_type": "SMART.TAPOHUB", - "encrypt_info": { - "data": "", - "key": "", - "sym_schm": "AES" - }, - "encrypt_type": [ - "3" - ], - "factory_default": false, - "firmware_version": "1.3.2 Build 20240424 rel.75425", - "hardware_version": "1.0", - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "A8-6E-84-00-00-00", - "mgt_encrypt_schm": { - "is_support_https": true + "error_code": 0, + "result": { + "decrypted_data": { + "connect_ssid": "", + "connect_type": "wired", + "device_id": "0000000000000000000000000000000000000000", + "http_port": 443, + "owner": "00000000000000000000000000000000", + "sd_status": "offline" + }, + "device_id": "00000000000000000000000000000000", + "device_model": "H200", + "device_name": "#MASKED_NAME#", + "device_type": "SMART.TAPOHUB", + "encrypt_info": { + "data": "", + "key": "", + "sym_schm": "AES" + }, + "encrypt_type": [ + "3" + ], + "factory_default": false, + "firmware_version": "1.3.2 Build 20240424 rel.75425", + "hardware_version": "1.0", + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "A8-6E-84-00-00-00", + "mgt_encrypt_schm": { + "is_support_https": true + } } }, "getAlertConfig": {}, diff --git a/tests/fixtures/smartcam/H200(US)_1.0_1.3.6.json b/tests/fixtures/smartcam/H200(US)_1.0_1.3.6.json index f1a6ae15..26c03793 100644 --- a/tests/fixtures/smartcam/H200(US)_1.0_1.3.6.json +++ b/tests/fixtures/smartcam/H200(US)_1.0_1.3.6.json @@ -1,34 +1,37 @@ { "discovery_result": { - "decrypted_data": { - "connect_ssid": "", - "connect_type": "wired", - "device_id": "0000000000000000000000000000000000000000", - "http_port": 443, - "owner": "00000000000000000000000000000000", - "sd_status": "offline" - }, - "device_id": "00000000000000000000000000000000", - "device_model": "H200", - "device_name": "#MASKED_NAME#", - "device_type": "SMART.TAPOHUB", - "encrypt_info": { - "data": "", - "key": "", - "sym_schm": "AES" - }, - "encrypt_type": [ - "3" - ], - "factory_default": false, - "firmware_version": "1.3.6 Build 20240829 rel.71119", - "hardware_version": "1.0", - "ip": "127.0.0.123", - "isResetWiFi": false, - "is_support_iot_cloud": true, - "mac": "24-2F-D0-00-00-00", - "mgt_encrypt_schm": { - "is_support_https": true + "error_code": 0, + "result": { + "decrypted_data": { + "connect_ssid": "", + "connect_type": "wired", + "device_id": "0000000000000000000000000000000000000000", + "http_port": 443, + "owner": "00000000000000000000000000000000", + "sd_status": "offline" + }, + "device_id": "00000000000000000000000000000000", + "device_model": "H200", + "device_name": "#MASKED_NAME#", + "device_type": "SMART.TAPOHUB", + "encrypt_info": { + "data": "", + "key": "", + "sym_schm": "AES" + }, + "encrypt_type": [ + "3" + ], + "factory_default": false, + "firmware_version": "1.3.6 Build 20240829 rel.71119", + "hardware_version": "1.0", + "ip": "127.0.0.123", + "isResetWiFi": false, + "is_support_iot_cloud": true, + "mac": "24-2F-D0-00-00-00", + "mgt_encrypt_schm": { + "is_support_https": true + } } }, "getAlertConfig": {}, diff --git a/tests/fixtures/smartcam/TC65_1.0_1.3.9.json b/tests/fixtures/smartcam/TC65_1.0_1.3.9.json index 5b05a1b3..cec6b759 100644 --- a/tests/fixtures/smartcam/TC65_1.0_1.3.9.json +++ b/tests/fixtures/smartcam/TC65_1.0_1.3.9.json @@ -1,35 +1,38 @@ { "discovery_result": { - "decrypted_data": { - "connect_ssid": "0000000", - "connect_type": "wireless", - "device_id": "0000000000000000000000000000000000000000", - "http_port": 443, - "last_alarm_time": "1698149810", - "last_alarm_type": "motion", - "owner": "00000000000000000000000000000000", - "sd_status": "offline" - }, - "device_id": "00000000000000000000000000000000", - "device_model": "TC65", - "device_name": "#MASKED_NAME#", - "device_type": "SMART.IPCAMERA", - "encrypt_info": { - "data": "", - "key": "", - "sym_schm": "AES" - }, - "encrypt_type": [ - "3" - ], - "factory_default": false, - "firmware_version": "1.3.9 Build 231024 Rel.72919n(4555)", - "hardware_version": "1.0", - "ip": "127.0.0.123", - "is_support_iot_cloud": true, - "mac": "A8-6E-84-00-00-00", - "mgt_encrypt_schm": { - "is_support_https": true + "error_code": 0, + "result": { + "decrypted_data": { + "connect_ssid": "#MASKED_SSID#", + "connect_type": "wireless", + "device_id": "0000000000000000000000000000000000000000", + "http_port": 443, + "last_alarm_time": "1698149810", + "last_alarm_type": "motion", + "owner": "00000000000000000000000000000000", + "sd_status": "offline" + }, + "device_id": "00000000000000000000000000000000", + "device_model": "TC65", + "device_name": "#MASKED_NAME#", + "device_type": "SMART.IPCAMERA", + "encrypt_info": { + "data": "", + "key": "", + "sym_schm": "AES" + }, + "encrypt_type": [ + "3" + ], + "factory_default": false, + "firmware_version": "1.3.9 Build 231024 Rel.72919n(4555)", + "hardware_version": "1.0", + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "A8-6E-84-00-00-00", + "mgt_encrypt_schm": { + "is_support_https": true + } } }, "getAlertPlan": { diff --git a/tests/test_cli.py b/tests/test_cli.py index 4391b998..c14f6c8b 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1126,7 +1126,7 @@ async def test_feature_set_child(mocker, runner): mocker.patch("kasa.discover.Discover.discover_single", return_value=dummy_device) get_child_device = mocker.spy(dummy_device, "get_child_device") - child_id = "000000000000000000000000000000000000000001" + child_id = "SCRUBBED_CHILD_DEVICE_ID_1" res = await runner.invoke( cli, diff --git a/tests/test_devtools.py b/tests/test_devtools.py index e18243af..8bdd5746 100644 --- a/tests/test_devtools.py +++ b/tests/test_devtools.py @@ -29,11 +29,13 @@ async def test_fixture_names(fixture_info: FixtureInfo): """Test that device info gets the right fixture names.""" if fixture_info.protocol in {"SMARTCAM"}: device_info = SmartCamDevice._get_device_info( - fixture_info.data, fixture_info.data.get("discovery_result") + fixture_info.data, + fixture_info.data.get("discovery_result", {}).get("result"), ) elif fixture_info.protocol in {"SMART"}: device_info = SmartDevice._get_device_info( - fixture_info.data, fixture_info.data.get("discovery_result") + fixture_info.data, + fixture_info.data.get("discovery_result", {}).get("result"), ) elif fixture_info.protocol in {"SMART.CHILD"}: device_info = SmartDevice._get_device_info(fixture_info.data, None) diff --git a/tests/test_readme_examples.py b/tests/test_readme_examples.py index 394a3aff..01294399 100644 --- a/tests/test_readme_examples.py +++ b/tests/test_readme_examples.py @@ -22,6 +22,9 @@ def test_bulb_examples(mocker): def test_smartdevice_examples(mocker): """Use HS110 for emeter examples.""" p = asyncio.run(get_device_for_fixture_protocol("HS110(EU)_1.0_1.2.5.json", "IOT")) + asyncio.run(p.set_alias("Bedroom Lamp Plug")) + asyncio.run(p.update()) + mocker.patch("kasa.iot.iotdevice.IotDevice", return_value=p) mocker.patch("kasa.iot.iotdevice.IotDevice.update") res = xdoctest.doctest_module("kasa.iot.iotdevice", "all") @@ -31,18 +34,16 @@ def test_smartdevice_examples(mocker): def test_plug_examples(mocker): """Test plug examples.""" p = asyncio.run(get_device_for_fixture_protocol("HS110(EU)_1.0_1.2.5.json", "IOT")) - # p = await get_device_for_fixture_protocol("HS110(EU)_1.0_1.2.5.json", "IOT") + asyncio.run(p.set_alias("Bedroom Lamp Plug")) + asyncio.run(p.update()) mocker.patch("kasa.iot.iotplug.IotPlug", return_value=p) mocker.patch("kasa.iot.iotplug.IotPlug.update") res = xdoctest.doctest_module("kasa.iot.iotplug", "all") assert not res["failed"] -def test_strip_examples(mocker): +def test_strip_examples(readmes_mock): """Test strip examples.""" - p = asyncio.run(get_device_for_fixture_protocol("KP303(UK)_1.0_1.0.3.json", "IOT")) - mocker.patch("kasa.iot.iotstrip.IotStrip", return_value=p) - mocker.patch("kasa.iot.iotstrip.IotStrip.update") res = xdoctest.doctest_module("kasa.iot.iotstrip", "all") assert not res["failed"] @@ -59,6 +60,8 @@ def test_dimmer_examples(mocker): def test_lightstrip_examples(mocker): """Test lightstrip examples.""" p = asyncio.run(get_device_for_fixture_protocol("KL430(US)_1.0_1.0.10.json", "IOT")) + asyncio.run(p.set_alias("Bedroom Lightstrip")) + asyncio.run(p.update()) mocker.patch("kasa.iot.iotlightstrip.IotLightStrip", return_value=p) mocker.patch("kasa.iot.iotlightstrip.IotLightStrip.update") res = xdoctest.doctest_module("kasa.iot.iotlightstrip", "all") @@ -154,4 +157,23 @@ async def readmes_mock(mocker): "127.0.0.4": get_fixture_info("KL430(US)_1.0_1.0.10.json", "IOT"), # Lightstrip "127.0.0.5": get_fixture_info("HS220(US)_1.0_1.5.7.json", "IOT"), # Dimmer } + fixture_infos["127.0.0.1"].data["system"]["get_sysinfo"]["alias"] = ( + "Bedroom Power Strip" + ) + for index, child in enumerate( + fixture_infos["127.0.0.1"].data["system"]["get_sysinfo"]["children"] + ): + child["alias"] = f"Plug {index + 1}" + fixture_infos["127.0.0.2"].data["system"]["get_sysinfo"]["alias"] = ( + "Bedroom Lamp Plug" + ) + fixture_infos["127.0.0.3"].data["get_device_info"]["nickname"] = ( + "TGl2aW5nIFJvb20gQnVsYg==" # Living Room Bulb + ) + fixture_infos["127.0.0.4"].data["system"]["get_sysinfo"]["alias"] = ( + "Bedroom Lightstrip" + ) + fixture_infos["127.0.0.5"].data["system"]["get_sysinfo"]["alias"] = ( + "Living Room Dimmer Switch" + ) return patch_discovery(fixture_infos, mocker) From f8a46f74cda2c77be004eb41302c7dbc33fede74 Mon Sep 17 00:00:00 2001 From: "Steven B." <51370195+sdb9696@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:38:38 +0000 Subject: [PATCH 5/5] Pass raw components to SmartChildDevice init (#1363) Clean up and consolidate the processing of raw component query responses and simplify the code paths for creating smartcam child devices when supported. --- kasa/smart/smartchilddevice.py | 11 ++++++----- kasa/smart/smartdevice.py | 28 +++++++++++++++----------- kasa/smartcam/smartcamdevice.py | 35 +++++++++++++++------------------ tests/test_childdevice.py | 4 +++- tests/test_device.py | 12 +++++++++-- 5 files changed, 51 insertions(+), 39 deletions(-) diff --git a/kasa/smart/smartchilddevice.py b/kasa/smart/smartchilddevice.py index db3319f3..d49e814c 100644 --- a/kasa/smart/smartchilddevice.py +++ b/kasa/smart/smartchilddevice.py @@ -9,7 +9,7 @@ from typing import Any from ..device_type import DeviceType from ..deviceconfig import DeviceConfig from ..protocols.smartprotocol import SmartProtocol, _ChildProtocolWrapper -from .smartdevice import SmartDevice +from .smartdevice import ComponentsRaw, SmartDevice from .smartmodule import SmartModule _LOGGER = logging.getLogger(__name__) @@ -37,7 +37,7 @@ class SmartChildDevice(SmartDevice): self, parent: SmartDevice, info: dict, - component_info: dict, + component_info_raw: ComponentsRaw, *, config: DeviceConfig | None = None, protocol: SmartProtocol | None = None, @@ -47,7 +47,8 @@ class SmartChildDevice(SmartDevice): super().__init__(parent.host, config=parent.config, protocol=_protocol) self._parent = parent self._update_internal_state(info) - self._components = component_info + self._components_raw = component_info_raw + self._components = self._parse_components(self._components_raw) async def update(self, update_children: bool = True) -> None: """Update child module info. @@ -84,7 +85,7 @@ class SmartChildDevice(SmartDevice): cls, parent: SmartDevice, child_info: dict, - child_components: dict, + child_components_raw: ComponentsRaw, protocol: SmartProtocol | None = None, *, last_update: dict | None = None, @@ -97,7 +98,7 @@ class SmartChildDevice(SmartDevice): derived from the parent. """ child: SmartChildDevice = cls( - parent, child_info, child_components, protocol=protocol + parent, child_info, child_components_raw, protocol=protocol ) if last_update: child._last_update = last_update diff --git a/kasa/smart/smartdevice.py b/kasa/smart/smartdevice.py index ed5a4eec..b9550352 100644 --- a/kasa/smart/smartdevice.py +++ b/kasa/smart/smartdevice.py @@ -7,7 +7,7 @@ import logging import time from collections.abc import Mapping, Sequence from datetime import UTC, datetime, timedelta, tzinfo -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, Any, TypeAlias, cast from ..device import Device, WifiNetwork, _DeviceInfo from ..device_type import DeviceType @@ -40,6 +40,8 @@ _LOGGER = logging.getLogger(__name__) # same issue, homekit perhaps? NON_HUB_PARENT_ONLY_MODULES = [DeviceModule, Time, Firmware, Cloud] +ComponentsRaw: TypeAlias = dict[str, list[dict[str, int | str]]] + # Device must go last as the other interfaces also inherit Device # and python needs a consistent method resolution order. @@ -61,7 +63,7 @@ class SmartDevice(Device): ) super().__init__(host=host, config=config, protocol=_protocol) self.protocol: SmartProtocol - self._components_raw: dict[str, Any] | None = None + self._components_raw: ComponentsRaw | None = None self._components: dict[str, int] = {} self._state_information: dict[str, Any] = {} self._modules: dict[str | ModuleName[Module], SmartModule] = {} @@ -82,10 +84,8 @@ class SmartDevice(Device): self.internal_state.update(resp) children = self.internal_state["get_child_device_list"]["child_device_list"] - children_components = { - child["device_id"]: { - comp["id"]: int(comp["ver_code"]) for comp in child["component_list"] - } + children_components_raw = { + child["device_id"]: child for child in self.internal_state["get_child_device_component_list"][ "child_component_list" ] @@ -96,7 +96,7 @@ class SmartDevice(Device): child_info["device_id"]: await SmartChildDevice.create( parent=self, child_info=child_info, - child_components=children_components[child_info["device_id"]], + child_components_raw=children_components_raw[child_info["device_id"]], ) for child_info in children } @@ -131,6 +131,13 @@ class SmartDevice(Device): f"{request} not found in {responses} for device {self.host}" ) + @staticmethod + def _parse_components(components_raw: ComponentsRaw) -> dict[str, int]: + return { + str(comp["id"]): int(comp["ver_code"]) + for comp in components_raw["component_list"] + } + async def _negotiate(self) -> None: """Perform initialization. @@ -151,12 +158,9 @@ class SmartDevice(Device): self._info = self._try_get_response(resp, "get_device_info") # Create our internal presentation of available components - self._components_raw = cast(dict, resp["component_nego"]) + self._components_raw = cast(ComponentsRaw, resp["component_nego"]) - self._components = { - comp["id"]: int(comp["ver_code"]) - for comp in self._components_raw["component_list"] - } + self._components = self._parse_components(self._components_raw) if "child_device" in self._components and not self.children: await self._initialize_children() diff --git a/kasa/smartcam/smartcamdevice.py b/kasa/smartcam/smartcamdevice.py index 0090117e..b383a4b4 100644 --- a/kasa/smartcam/smartcamdevice.py +++ b/kasa/smartcam/smartcamdevice.py @@ -3,13 +3,14 @@ from __future__ import annotations import logging -from typing import Any +from typing import Any, cast from ..device import _DeviceInfo from ..device_type import DeviceType from ..module import Module from ..protocols.smartcamprotocol import _ChildCameraProtocolWrapper from ..smart import SmartChildDevice, SmartDevice +from ..smart.smartdevice import ComponentsRaw from .modules import ChildDevice, DeviceModule from .smartcammodule import SmartCamModule @@ -78,7 +79,7 @@ class SmartCamDevice(SmartDevice): self._children[child_id]._update_internal_state(info) async def _initialize_smart_child( - self, info: dict, child_components: dict + self, info: dict, child_components_raw: ComponentsRaw ) -> SmartDevice: """Initialize a smart child device attached to a smartcam device.""" child_id = info["device_id"] @@ -93,7 +94,7 @@ class SmartCamDevice(SmartDevice): return await SmartChildDevice.create( parent=self, child_info=info, - child_components=child_components, + child_components_raw=child_components_raw, protocol=child_protocol, last_update=initial_response, ) @@ -108,17 +109,8 @@ class SmartCamDevice(SmartDevice): self.internal_state.update(resp) smart_children_components = { - child["device_id"]: { - comp["id"]: int(comp["ver_code"]) for comp in component_list - } + child["device_id"]: child for child in resp["getChildDeviceComponentList"]["child_component_list"] - if (component_list := child.get("component_list")) - # Child camera devices will have a different component schema so only - # extract smart values. - and (first_comp := next(iter(component_list), None)) - and isinstance(first_comp, dict) - and "id" in first_comp - and "ver_code" in first_comp } children = {} for info in resp["getChildDeviceList"]["child_device_list"]: @@ -172,6 +164,13 @@ class SmartCamDevice(SmartDevice): return res + @staticmethod + def _parse_components(components_raw: ComponentsRaw) -> dict[str, int]: + return { + str(comp["name"]): int(comp["version"]) + for comp in components_raw["app_component_list"] + } + async def _negotiate(self) -> None: """Perform initialization. @@ -186,12 +185,10 @@ class SmartCamDevice(SmartDevice): self._last_update.update(resp) self._update_internal_info(resp) - self._components = { - comp["name"]: int(comp["version"]) - for comp in resp["getAppComponentList"]["app_component"][ - "app_component_list" - ] - } + self._components_raw = cast( + ComponentsRaw, resp["getAppComponentList"]["app_component"] + ) + self._components = self._parse_components(self._components_raw) if "childControl" in self._components and not self.children: await self._initialize_children() diff --git a/tests/test_childdevice.py b/tests/test_childdevice.py index 1e525efb..8bcc05db 100644 --- a/tests/test_childdevice.py +++ b/tests/test_childdevice.py @@ -145,7 +145,9 @@ async def test_child_device_type_unknown(caplog): super().__init__( SmartDevice("127.0.0.1"), {"device_id": "1", "category": "foobar"}, - {"device", 1}, + { + "component_list": [{"id": "device", "ver_code": 1}], + }, ) assert DummyDevice().device_type is DeviceType.Unknown diff --git a/tests/test_device.py b/tests/test_device.py index 0764acfb..45de4a28 100644 --- a/tests/test_device.py +++ b/tests/test_device.py @@ -86,7 +86,11 @@ async def test_device_class_ctors(device_class_name_obj): if issubclass(klass, SmartChildDevice): parent = SmartDevice(host, config=config) dev = klass( - parent, {"dummy": "info", "device_id": "dummy"}, {"dummy": "components"} + parent, + {"dummy": "info", "device_id": "dummy"}, + { + "component_list": [{"id": "device", "ver_code": 1}], + }, ) else: dev = klass(host, config=config) @@ -106,7 +110,11 @@ async def test_device_class_repr(device_class_name_obj): if issubclass(klass, SmartChildDevice): parent = SmartDevice(host, config=config) dev = klass( - parent, {"dummy": "info", "device_id": "dummy"}, {"dummy": "components"} + parent, + {"dummy": "info", "device_id": "dummy"}, + { + "component_list": [{"id": "device", "ver_code": 1}], + }, ) else: dev = klass(host, config=config)