Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Change state_information to return feature values #804

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions kasa/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,16 +609,7 @@ async def state(ctx, dev: Device):
echo(f"\tMAC (rssi): {dev.mac} ({dev.rssi})")
echo(f"\tLocation: {dev.location}")

echo("\n\t[bold]== Device specific information ==[/bold]")
for info_name, info_data in dev.state_information.items():
if isinstance(info_data, list):
echo(f"\t{info_name}:")
for item in info_data:
echo(f"\t\t{item}")
else:
echo(f"\t{info_name}: {info_data}")

echo("\n\t[bold]== Features == [/bold]")
echo("\n\t[bold]== Device-specific information == [/bold]")
for id_, feature in dev.features.items():
echo(f"\t{feature.name} ({id_}): {feature.value}")

Expand Down
4 changes: 2 additions & 2 deletions kasa/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,9 @@ def internal_state(self) -> Any:
"""Return all the internal state data."""

@property
@abstractmethod
def state_information(self) -> Dict[str, Any]:
"""Return the key state information."""
"""Return available features and their values."""
return {feat.name: feat.value for feat in self._features.values()}

@property
def features(self) -> Dict[str, Feature]:
Expand Down
19 changes: 1 addition & 18 deletions kasa/iot/iotbulb.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging
import re
from enum import Enum
from typing import Any, Dict, List, Optional, cast
from typing import Dict, List, Optional, cast

try:
from pydantic.v1 import BaseModel, Field, root_validator
Expand Down Expand Up @@ -445,23 +445,6 @@ async def set_brightness(
light_state = {"brightness": brightness}
return await self.set_light_state(light_state, transition=transition)

@property # type: ignore
@requires_update
def state_information(self) -> Dict[str, Any]:
"""Return bulb-specific state information."""
info: Dict[str, Any] = {
"Brightness": self.brightness,
"Is dimmable": self.is_dimmable,
}
if self.is_variable_color_temp:
info["Color temperature"] = self.color_temp
info["Valid temperature range"] = self.valid_temperature_range
if self.is_color:
info["HSV"] = self.hsv
info["Presets"] = self.presets

return info

@property # type: ignore
@requires_update
def is_on(self) -> bool:
Expand Down
6 changes: 0 additions & 6 deletions kasa/iot/iotdevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,12 +615,6 @@ def on_since(self) -> Optional[datetime]:

return datetime.now().replace(microsecond=0) - timedelta(seconds=on_time)

@property # type: ignore
@requires_update
def state_information(self) -> Dict[str, Any]:
"""Return device-type specific, end-user friendly state information."""
raise NotImplementedError("Device subclass needs to implement this.")

@property # type: ignore
@requires_update
def device_id(self) -> str:
Expand Down
9 changes: 0 additions & 9 deletions kasa/iot/iotdimmer.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,3 @@ def is_dimmable(self) -> bool:
"""Whether the switch supports brightness changes."""
sys_info = self.sys_info
return "brightness" in sys_info

@property # type: ignore
@requires_update
def state_information(self) -> Dict[str, Any]:
"""Return switch-specific state information."""
info = super().state_information
info["Brightness"] = self.brightness

return info
14 changes: 1 addition & 13 deletions kasa/iot/iotlightstrip.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Module for light strips (KL430)."""
from typing import Any, Dict, List, Optional
from typing import Dict, List, Optional

from ..device_type import DeviceType
from ..deviceconfig import DeviceConfig
Expand Down Expand Up @@ -84,18 +84,6 @@ def effect_list(self) -> Optional[List[str]]:
"""
return EFFECT_NAMES_V1 if self.has_effects else None

@property # type: ignore
@requires_update
def state_information(self) -> Dict[str, Any]:
"""Return strip specific state information."""
info = super().state_information

info["Length"] = self.length
if self.has_effects:
info["Effect"] = self.effect["name"]

return info

@requires_update
async def set_effect(
self,
Expand Down
8 changes: 1 addition & 7 deletions kasa/iot/iotplug.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Module for smart plugs (HS100, HS110, ..)."""
import logging
from typing import Any, Dict, Optional
from typing import Optional

from ..device_type import DeviceType
from ..deviceconfig import DeviceConfig
Expand Down Expand Up @@ -96,12 +96,6 @@ async def set_led(self, state: bool):
"system", "set_led_off", {"off": int(not state)}
)

@property # type: ignore
@requires_update
def state_information(self) -> Dict[str, Any]:
"""Return switch-specific state information."""
return {}


class IotWallSwitch(IotPlug):
"""Representation of a TP-Link Smart Wall Switch."""
Expand Down
13 changes: 0 additions & 13 deletions kasa/iot/iotstrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,6 @@ async def set_led(self, state: bool):
"""Set the state of the led (night mode)."""
await self._query_helper("system", "set_led_off", {"off": int(not state)})

@property # type: ignore
@requires_update
def state_information(self) -> Dict[str, Any]:
"""Return strip-specific state information.

:return: Strip information dict, keys in user-presentable form.
"""
return {
"LED state": self.led,
"Childs count": len(self.children),
"On since": self.on_since,
}

async def current_consumption(self) -> float:
"""Get the current power consumption in watts."""
return sum([await plug.current_consumption() for plug in self.children])
Expand Down
21 changes: 1 addition & 20 deletions kasa/smart/smartbulb.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Module for tapo-branded smart bulbs (L5**)."""
from typing import Any, Dict, List, Optional
from typing import Dict, List, Optional

from ..bulb import Bulb
from ..exceptions import KasaException
Expand Down Expand Up @@ -238,25 +238,6 @@ async def set_effect(
}
)

@property # type: ignore
def state_information(self) -> Dict[str, Any]:
"""Return bulb-specific state information."""
info: Dict[str, Any] = {
# TODO: re-enable after we don't inherit from smartbulb
# **super().state_information
"Is dimmable": self.is_dimmable,
}
if self.is_dimmable:
info["Brightness"] = self.brightness
if self.is_variable_color_temp:
info["Color temperature"] = self.color_temp
info["Valid temperature range"] = self.valid_temperature_range
if self.is_color:
info["HSV"] = self.hsv
info["Presets"] = self.presets

return info

@property
def presets(self) -> List[BulbPreset]:
"""Return a list of available bulb setting presets."""
Expand Down
9 changes: 0 additions & 9 deletions kasa/smart/smartdevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,15 +319,6 @@ def ssid(self) -> str:
ssid = base64.b64decode(ssid).decode() if ssid else "No SSID"
return ssid

@property
def state_information(self) -> Dict[str, Any]:
"""Return the key state information."""
return {
"overheated": self._info.get("overheated"),
"signal_level": self._info.get("signal_level"),
"SSID": self.ssid,
}

@property
def has_emeter(self) -> bool:
"""Return if the device has emeter."""
Expand Down
61 changes: 59 additions & 2 deletions kasa/tests/fakeprotocol_iot.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,61 @@ def success(res):
"set_timezone": None,
}

CLOUD_MODULE = {
"get_info": {
"username": "",
"server": "devs.tplinkcloud.com",
"binded": 0,
"cld_connection": 0,
"illegalType": -1,
"stopConnect": -1,
"tcspStatus": -1,
"fwDlPage": "",
"tcspInfo": "",
"fwNotifyType": 0,
}
}


AMBIENT_MODULE = {
"get_current_brt": {"value": 26, "err_code": 0},
"get_config": {
"devs": [
{
"hw_id": 0,
"enable": 0,
"dark_index": 1,
"min_adc": 0,
"max_adc": 2450,
"level_array": [
{"name": "cloudy", "adc": 490, "value": 20},
{"name": "overcast", "adc": 294, "value": 12},
{"name": "dawn", "adc": 222, "value": 9},
{"name": "twilight", "adc": 222, "value": 9},
{"name": "total darkness", "adc": 111, "value": 4},
{"name": "custom", "adc": 2400, "value": 97},
],
}
],
"ver": "1.0",
"err_code": 0,
},
}


MOTION_MODULE = {
"get_config": {
"enable": 0,
"version": "1.0",
"trigger_index": 2,
"cold_time": 60000,
"min_adc": 0,
"max_adc": 4095,
"array": [80, 50, 20, 0],
"err_code": 0,
}
}


class FakeIotProtocol(IotProtocol):
def __init__(self, info):
Expand Down Expand Up @@ -306,8 +361,10 @@ def light_state(self, x, *args):
"set_brightness": set_hs220_brightness,
"set_dimmer_transition": set_hs220_dimmer_transition,
},
"smartlife.iot.LAS": {},
"smartlife.iot.PIR": {},
"smartlife.iot.LAS": AMBIENT_MODULE,
"smartlife.iot.PIR": MOTION_MODULE,
"cnCloud": CLOUD_MODULE,
"smartlife.iot.common.cloud": CLOUD_MODULE,
}

async def query(self, request, port=9999):
Expand Down
9 changes: 4 additions & 5 deletions kasa/tests/test_bulb.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,8 @@ async def test_bulb_sysinfo(dev: Bulb):

@bulb
async def test_state_attributes(dev: Bulb):
assert "Brightness" in dev.state_information
assert dev.state_information["Brightness"] == dev.brightness

assert "Is dimmable" in dev.state_information
assert dev.state_information["Is dimmable"] == dev.is_dimmable
assert "Cloud connection" in dev.state_information
assert isinstance(dev.state_information["Cloud connection"], bool)


@bulb_iot
Expand Down Expand Up @@ -114,6 +111,7 @@ async def test_invalid_hsv(dev: Bulb, turn_on):


@color_bulb
@pytest.mark.skip("requires color feature")
async def test_color_state_information(dev: Bulb):
assert "HSV" in dev.state_information
assert dev.state_information["HSV"] == dev.hsv
Expand All @@ -130,6 +128,7 @@ async def test_hsv_on_non_color(dev: Bulb):


@variable_temp
@pytest.mark.skip("requires colortemp module")
async def test_variable_temp_state_information(dev: Bulb):
assert "Color temperature" in dev.state_information
assert dev.state_information["Color temperature"] == dev.color_temp
Expand Down
1 change: 0 additions & 1 deletion kasa/tests/test_lightstrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ async def test_effects_lightstrip_set_effect(dev: IotLightStrip):

await dev.set_effect("Candy Cane")
assert dev.effect["name"] == "Candy Cane"
assert dev.state_information["Effect"] == "Candy Cane"


@lightstrip
Expand Down