From 40f2263770ac917c3a851e9c2e5ad01982ce4921 Mon Sep 17 00:00:00 2001 From: Teemu R Date: Tue, 4 Jun 2024 19:24:53 +0200 Subject: [PATCH] Add some device fixtures (#948) Adds some device fixtures by courtesy of @jimboca, thanks! This is a slightly patched and rebased version of #441. --------- Co-authored-by: JimBo Co-authored-by: sdb9696 --- SUPPORTED.md | 3 + kasa/iot/iotlightstrip.py | 3 +- kasa/iot/modules/lightpreset.py | 7 +- kasa/tests/fixtures/HS110(US)_1.0_1.2.6.json | 37 ++++++++ kasa/tests/fixtures/HS300(US)_1.0_1.0.21.json | 89 +++++++++++++++++++ kasa/tests/fixtures/KL120(US)_1.0_1.8.11.json | 85 ++++++++++++++++++ kasa/tests/fixtures/KL430(US)_1.0_1.0.10.json | 61 ++++++++++--- kasa/tests/test_bulb.py | 11 ++- 8 files changed, 280 insertions(+), 16 deletions(-) create mode 100644 kasa/tests/fixtures/HS110(US)_1.0_1.2.6.json create mode 100644 kasa/tests/fixtures/HS300(US)_1.0_1.0.21.json create mode 100644 kasa/tests/fixtures/KL120(US)_1.0_1.8.11.json diff --git a/SUPPORTED.md b/SUPPORTED.md index 252f075d..dd63dbc9 100644 --- a/SUPPORTED.md +++ b/SUPPORTED.md @@ -29,6 +29,7 @@ Some newer Kasa devices require authentication. These are marked with ***>> strip.effect - {'brightness': 50, 'custom': 0, 'enable': 0, 'id': '', 'name': ''} + {'brightness': 100, 'custom': 0, 'enable': 0, + 'id': 'bCTItKETDFfrKANolgldxfgOakaarARs', 'name': 'Flicker'} .. note:: The device supports some features that are not currently implemented, diff --git a/kasa/iot/modules/lightpreset.py b/kasa/iot/modules/lightpreset.py index 49eca3b8..d9fbb7fa 100644 --- a/kasa/iot/modules/lightpreset.py +++ b/kasa/iot/modules/lightpreset.py @@ -45,6 +45,9 @@ class LightPreset(IotModule, LightPresetInterface): self._presets = { f"Light preset {index+1}": IotLightPreset(**vals) for index, vals in enumerate(self.data["preferred_state"]) + # Devices may list some light effects along with normal presets but these + # are handled by the LightEffect module so exclude preferred states with id + if "id" not in vals } self._preset_list = [self.PRESET_NOT_SET] self._preset_list.extend(self._presets.keys()) @@ -133,7 +136,9 @@ class LightPreset(IotModule, LightPresetInterface): def _deprecated_presets(self) -> list[IotLightPreset]: """Return a list of available bulb setting presets.""" return [ - IotLightPreset(**vals) for vals in self._device.sys_info["preferred_state"] + IotLightPreset(**vals) + for vals in self._device.sys_info["preferred_state"] + if "id" not in vals ] async def _deprecated_save_preset(self, preset: IotLightPreset): diff --git a/kasa/tests/fixtures/HS110(US)_1.0_1.2.6.json b/kasa/tests/fixtures/HS110(US)_1.0_1.2.6.json new file mode 100644 index 00000000..5e285e72 --- /dev/null +++ b/kasa/tests/fixtures/HS110(US)_1.0_1.2.6.json @@ -0,0 +1,37 @@ +{ + "emeter": { + "get_realtime": { + "current": 0.128037, + "err_code": 0, + "power": 7.677094, + "total": 30.404, + "voltage": 118.917389 + } + }, + "system": { + "get_sysinfo": { + "active_mode": "schedule", + "alias": "Home Google WiFi HS110", + "dev_name": "Wi-Fi Smart Plug With Energy Monitoring", + "deviceId": "0000000000000000000000000000000000000000", + "err_code": 0, + "feature": "TIM:ENE", + "fwId": "00000000000000000000000000000000", + "hwId": "00000000000000000000000000000000", + "hw_ver": "1.0", + "icon_hash": "", + "latitude": 0, + "led_off": 0, + "longitude": 0, + "mac": "00:00:00:00:00:00", + "model": "HS110(US)", + "oemId": "00000000000000000000000000000000", + "on_time": 14048150, + "relay_state": 1, + "rssi": -38, + "sw_ver": "1.2.6 Build 200727 Rel.121701", + "type": "IOT.SMARTPLUGSWITCH", + "updating": 0 + } + } +} diff --git a/kasa/tests/fixtures/HS300(US)_1.0_1.0.21.json b/kasa/tests/fixtures/HS300(US)_1.0_1.0.21.json new file mode 100644 index 00000000..388fadf3 --- /dev/null +++ b/kasa/tests/fixtures/HS300(US)_1.0_1.0.21.json @@ -0,0 +1,89 @@ +{ + "emeter": { + "get_realtime": { + "current_ma": 544, + "err_code": 0, + "power_mw": 62430, + "total_wh": 26889, + "voltage_mv": 118389 + } + }, + "system": { + "get_sysinfo": { + "alias": "TP-LINK_Power Strip_2CA9", + "child_num": 6, + "children": [ + { + "alias": "Home CameraPC", + "id": "800623145DFF1AA096363EFD161C2E661A9D8DED00", + "next_action": { + "type": -1 + }, + "on_time": 1449897, + "state": 1 + }, + { + "alias": "Home Firewalla", + "id": "800623145DFF1AA096363EFD161C2E661A9D8DED01", + "next_action": { + "type": -1 + }, + "on_time": 1449897, + "state": 1 + }, + { + "alias": "Home Cox modem", + "id": "800623145DFF1AA096363EFD161C2E661A9D8DED02", + "next_action": { + "type": -1 + }, + "on_time": 1449897, + "state": 1 + }, + { + "alias": "Home rpi3-2", + "id": "800623145DFF1AA096363EFD161C2E661A9D8DED03", + "next_action": { + "type": -1 + }, + "on_time": 1449897, + "state": 1 + }, + { + "alias": "Home Camera Switch", + "id": "800623145DFF1AA096363EFD161C2E661A9D8DED05", + "next_action": { + "type": -1 + }, + "on_time": 1449897, + "state": 1 + }, + { + "alias": "Home Network Switch", + "id": "800623145DFF1AA096363EFD161C2E661A9D8DED04", + "next_action": { + "type": -1 + }, + "on_time": 1449897, + "state": 1 + } + ], + "deviceId": "0000000000000000000000000000000000000000", + "err_code": 0, + "feature": "TIM:ENE", + "hwId": "00000000000000000000000000000000", + "hw_ver": "1.0", + "latitude_i": 0, + "led_off": 0, + "longitude_i": 0, + "mac": "00:00:00:00:00:00", + "mic_type": "IOT.SMARTPLUGSWITCH", + "model": "HS300(US)", + "oemId": "00000000000000000000000000000000", + "rssi": -39, + "status": "new", + "sw_ver": "1.0.21 Build 210524 Rel.161309", + "updating": 0 + } + } +} diff --git a/kasa/tests/fixtures/KL120(US)_1.0_1.8.11.json b/kasa/tests/fixtures/KL120(US)_1.0_1.8.11.json new file mode 100644 index 00000000..1d8e1fce --- /dev/null +++ b/kasa/tests/fixtures/KL120(US)_1.0_1.8.11.json @@ -0,0 +1,85 @@ +{ + "smartlife.iot.common.emeter": { + "get_realtime": { + "err_code": 0, + "power_mw": 7800 + } + }, + "smartlife.iot.smartbulb.lightingservice": { + "get_light_state": { + "brightness": 70, + "color_temp": 3001, + "err_code": 0, + "hue": 0, + "mode": "normal", + "on_off": 1, + "saturation": 0 + } + }, + "system": { + "get_sysinfo": { + "active_mode": "none", + "alias": "Home Family Room Table", + "ctrl_protocols": { + "name": "Linkie", + "version": "1.0" + }, + "description": "Smart Wi-Fi LED Bulb with Tunable White Light", + "dev_state": "normal", + "deviceId": "0000000000000000000000000000000000000000", + "disco_ver": "1.0", + "err_code": 0, + "heapsize": 292140, + "hwId": "00000000000000000000000000000000", + "hw_ver": "1.0", + "is_color": 0, + "is_dimmable": 1, + "is_factory": false, + "is_variable_color_temp": 1, + "light_state": { + "brightness": 70, + "color_temp": 3001, + "hue": 0, + "mode": "normal", + "on_off": 1, + "saturation": 0 + }, + "mic_mac": "000000000000", + "mic_type": "IOT.SMARTBULB", + "model": "KL120(US)", + "oemId": "00000000000000000000000000000000", + "preferred_state": [ + { + "brightness": 100, + "color_temp": 3500, + "hue": 0, + "index": 0, + "saturation": 0 + }, + { + "brightness": 50, + "color_temp": 5000, + "hue": 0, + "index": 1, + "saturation": 0 + }, + { + "brightness": 50, + "color_temp": 2700, + "hue": 0, + "index": 2, + "saturation": 0 + }, + { + "brightness": 1, + "color_temp": 2700, + "hue": 0, + "index": 3, + "saturation": 0 + } + ], + "rssi": -45, + "sw_ver": "1.8.11 Build 191113 Rel.105336" + } + } +} diff --git a/kasa/tests/fixtures/KL430(US)_1.0_1.0.10.json b/kasa/tests/fixtures/KL430(US)_1.0_1.0.10.json index 793452ae..9b6d8413 100644 --- a/kasa/tests/fixtures/KL430(US)_1.0_1.0.10.json +++ b/kasa/tests/fixtures/KL430(US)_1.0_1.0.10.json @@ -7,8 +7,8 @@ "get_realtime": { "current_ma": 0, "err_code": 0, - "power_mw": 8729, - "total_wh": 21, + "power_mw": 2725, + "total_wh": 1193, "voltage_mv": 0 } }, @@ -22,7 +22,7 @@ }, "system": { "get_sysinfo": { - "active_mode": "none", + "active_mode": "schedule", "alias": "Bedroom Lightstrip", "ctrl_protocols": { "name": "Linkie", @@ -42,27 +42,66 @@ "latitude_i": 0, "length": 16, "light_state": { - "brightness": 50, - "color_temp": 3630, + "brightness": 15, + "color_temp": 2500, "hue": 0, "mode": "normal", "on_off": 1, "saturation": 0 }, "lighting_effect_state": { - "brightness": 50, + "brightness": 100, "custom": 0, "enable": 0, - "id": "", - "name": "" + "id": "bCTItKETDFfrKANolgldxfgOakaarARs", + "name": "Flicker" }, "longitude_i": 0, - "mic_mac": "CC32E5230F55", + "mic_mac": "CC32E5000000", "mic_type": "IOT.SMARTBULB", "model": "KL430(US)", "oemId": "00000000000000000000000000000000", - "preferred_state": [], - "rssi": -56, + "preferred_state": [ + { + "brightness": 100, + "custom": 0, + "id": "QglBhMShPHUAuxLqzNEefFrGiJwahOmz", + "index": 0, + "mode": 2 + }, + { + "brightness": 100, + "custom": 0, + "id": "bCTItKETDFfrKANolgldxfgOakaarARs", + "index": 1, + "mode": 2 + }, + { + "brightness": 34, + "color_temp": 0, + "hue": 7, + "index": 2, + "mode": 1, + "saturation": 49 + }, + { + "brightness": 25, + "color_temp": 0, + "hue": 4, + "index": 3, + "mode": 1, + "saturation": 100 + }, + { + "brightness": 15, + "color_temp": 2500, + "hue": 0, + "index": 4, + "mode": 1, + "saturation": 0 + } + ], + "rssi": -44, "status": "new", "sw_ver": "1.0.10 Build 200522 Rel.104340" } diff --git a/kasa/tests/test_bulb.py b/kasa/tests/test_bulb.py index b2653015..c78c539c 100644 --- a/kasa/tests/test_bulb.py +++ b/kasa/tests/test_bulb.py @@ -283,12 +283,17 @@ async def test_ignore_default_not_set_without_color_mode_change_turn_on( @bulb_iot async def test_list_presets(dev: IotBulb): presets = dev.presets - assert len(presets) == len(dev.sys_info["preferred_state"]) + # Light strip devices may list some light effects along with normal presets but these + # are handled by the LightEffect module so exclude preferred states with id + raw_presets = [ + pstate for pstate in dev.sys_info["preferred_state"] if "id" not in pstate + ] + assert len(presets) == len(raw_presets) - for preset, raw in zip(presets, dev.sys_info["preferred_state"]): + for preset, raw in zip(presets, raw_presets): assert preset.index == raw["index"] - assert preset.hue == raw["hue"] assert preset.brightness == raw["brightness"] + assert preset.hue == raw["hue"] assert preset.saturation == raw["saturation"] assert preset.color_temp == raw["color_temp"]