mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-04-27 09:06:24 +00:00
Remove SmartPlug in favor of SmartDevice (#781)
With the move towards autodetecting available features, there is no reason to keep SmartPlug around. kasa.smart.SmartPlug is removed in favor of kasa.smart.SmartDevice which offers the same functionality. Information about auto_off can be accessed using Features of the AutoOffModule on supported devices. Co-authored-by: Steven B. <51370195+sdb9696@users.noreply.github.com>
This commit is contained in:
parent
8c39e81a40
commit
d9d2f1a430
@ -134,7 +134,6 @@ if TYPE_CHECKING:
|
|||||||
from . import smart
|
from . import smart
|
||||||
|
|
||||||
smart.SmartDevice("127.0.0.1")
|
smart.SmartDevice("127.0.0.1")
|
||||||
smart.SmartPlug("127.0.0.1")
|
|
||||||
smart.SmartBulb("127.0.0.1")
|
smart.SmartBulb("127.0.0.1")
|
||||||
iot.IotDevice("127.0.0.1")
|
iot.IotDevice("127.0.0.1")
|
||||||
iot.IotPlug("127.0.0.1")
|
iot.IotPlug("127.0.0.1")
|
||||||
|
@ -27,7 +27,7 @@ from kasa import (
|
|||||||
)
|
)
|
||||||
from kasa.discover import DiscoveryResult
|
from kasa.discover import DiscoveryResult
|
||||||
from kasa.iot import IotBulb, IotDevice, IotDimmer, IotLightStrip, IotPlug, IotStrip
|
from kasa.iot import IotBulb, IotDevice, IotDimmer, IotLightStrip, IotPlug, IotStrip
|
||||||
from kasa.smart import SmartBulb, SmartDevice, SmartPlug
|
from kasa.smart import SmartBulb, SmartDevice
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from pydantic.v1 import ValidationError
|
from pydantic.v1 import ValidationError
|
||||||
@ -72,7 +72,7 @@ TYPE_TO_CLASS = {
|
|||||||
"iot.dimmer": IotDimmer,
|
"iot.dimmer": IotDimmer,
|
||||||
"iot.strip": IotStrip,
|
"iot.strip": IotStrip,
|
||||||
"iot.lightstrip": IotLightStrip,
|
"iot.lightstrip": IotLightStrip,
|
||||||
"smart.plug": SmartPlug,
|
"smart.plug": SmartDevice,
|
||||||
"smart.bulb": SmartBulb,
|
"smart.bulb": SmartBulb,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,32 +194,32 @@ class Device(ABC):
|
|||||||
@property
|
@property
|
||||||
def is_bulb(self) -> bool:
|
def is_bulb(self) -> bool:
|
||||||
"""Return True if the device is a bulb."""
|
"""Return True if the device is a bulb."""
|
||||||
return self._device_type == DeviceType.Bulb
|
return self.device_type == DeviceType.Bulb
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_light_strip(self) -> bool:
|
def is_light_strip(self) -> bool:
|
||||||
"""Return True if the device is a led strip."""
|
"""Return True if the device is a led strip."""
|
||||||
return self._device_type == DeviceType.LightStrip
|
return self.device_type == DeviceType.LightStrip
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_plug(self) -> bool:
|
def is_plug(self) -> bool:
|
||||||
"""Return True if the device is a plug."""
|
"""Return True if the device is a plug."""
|
||||||
return self._device_type == DeviceType.Plug
|
return self.device_type == DeviceType.Plug
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_strip(self) -> bool:
|
def is_strip(self) -> bool:
|
||||||
"""Return True if the device is a strip."""
|
"""Return True if the device is a strip."""
|
||||||
return self._device_type == DeviceType.Strip
|
return self.device_type == DeviceType.Strip
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_strip_socket(self) -> bool:
|
def is_strip_socket(self) -> bool:
|
||||||
"""Return True if the device is a strip socket."""
|
"""Return True if the device is a strip socket."""
|
||||||
return self._device_type == DeviceType.StripSocket
|
return self.device_type == DeviceType.StripSocket
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_dimmer(self) -> bool:
|
def is_dimmer(self) -> bool:
|
||||||
"""Return True if the device is a dimmer."""
|
"""Return True if the device is a dimmer."""
|
||||||
return self._device_type == DeviceType.Dimmer
|
return self.device_type == DeviceType.Dimmer
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_dimmable(self) -> bool:
|
def is_dimmable(self) -> bool:
|
||||||
@ -354,9 +354,9 @@ class Device(ABC):
|
|||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self._last_update is None:
|
if self._last_update is None:
|
||||||
return f"<{self._device_type} at {self.host} - update() needed>"
|
return f"<{self.device_type} at {self.host} - update() needed>"
|
||||||
return (
|
return (
|
||||||
f"<{self._device_type} model {self.model} at {self.host}"
|
f"<{self.device_type} model {self.model} at {self.host}"
|
||||||
f" ({self.alias}), is_on: {self.is_on}"
|
f" ({self.alias}), is_on: {self.is_on}"
|
||||||
f" - dev specific: {self.state_information}>"
|
f" - dev specific: {self.state_information}>"
|
||||||
)
|
)
|
||||||
|
@ -14,7 +14,7 @@ from .protocol import (
|
|||||||
BaseProtocol,
|
BaseProtocol,
|
||||||
BaseTransport,
|
BaseTransport,
|
||||||
)
|
)
|
||||||
from .smart import SmartBulb, SmartPlug
|
from .smart import SmartBulb, SmartDevice
|
||||||
from .smartprotocol import SmartProtocol
|
from .smartprotocol import SmartProtocol
|
||||||
from .xortransport import XorTransport
|
from .xortransport import XorTransport
|
||||||
|
|
||||||
@ -135,10 +135,10 @@ def get_device_class_from_sys_info(info: Dict[str, Any]) -> Type[IotDevice]:
|
|||||||
def get_device_class_from_family(device_type: str) -> Optional[Type[Device]]:
|
def get_device_class_from_family(device_type: str) -> Optional[Type[Device]]:
|
||||||
"""Return the device class from the type name."""
|
"""Return the device class from the type name."""
|
||||||
supported_device_types: Dict[str, Type[Device]] = {
|
supported_device_types: Dict[str, Type[Device]] = {
|
||||||
"SMART.TAPOPLUG": SmartPlug,
|
"SMART.TAPOPLUG": SmartDevice,
|
||||||
"SMART.TAPOBULB": SmartBulb,
|
"SMART.TAPOBULB": SmartBulb,
|
||||||
"SMART.TAPOSWITCH": SmartBulb,
|
"SMART.TAPOSWITCH": SmartBulb,
|
||||||
"SMART.KASAPLUG": SmartPlug,
|
"SMART.KASAPLUG": SmartDevice,
|
||||||
"SMART.KASASWITCH": SmartBulb,
|
"SMART.KASASWITCH": SmartBulb,
|
||||||
"IOT.SMARTPLUGSWITCH": IotPlug,
|
"IOT.SMARTPLUGSWITCH": IotPlug,
|
||||||
"IOT.SMARTBULB": IotBulb,
|
"IOT.SMARTBULB": IotBulb,
|
||||||
|
@ -2,6 +2,5 @@
|
|||||||
from .smartbulb import SmartBulb
|
from .smartbulb import SmartBulb
|
||||||
from .smartchilddevice import SmartChildDevice
|
from .smartchilddevice import SmartChildDevice
|
||||||
from .smartdevice import SmartDevice
|
from .smartdevice import SmartDevice
|
||||||
from .smartplug import SmartPlug
|
|
||||||
|
|
||||||
__all__ = ["SmartDevice", "SmartPlug", "SmartBulb", "SmartChildDevice"]
|
__all__ = ["SmartDevice", "SmartBulb", "SmartChildDevice"]
|
||||||
|
@ -485,3 +485,28 @@ class SmartDevice(Device):
|
|||||||
Note, this does not downgrade the firmware.
|
Note, this does not downgrade the firmware.
|
||||||
"""
|
"""
|
||||||
await self.protocol.query("device_reset")
|
await self.protocol.query("device_reset")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_type(self) -> DeviceType:
|
||||||
|
"""Return the device type."""
|
||||||
|
if self._device_type is not DeviceType.Unknown:
|
||||||
|
return self._device_type
|
||||||
|
|
||||||
|
if self.children:
|
||||||
|
if "SMART.TAPOHUB" in self.sys_info["type"]:
|
||||||
|
pass # TODO: placeholder for future hub PR
|
||||||
|
else:
|
||||||
|
self._device_type = DeviceType.Strip
|
||||||
|
elif "light_strip" in self._components:
|
||||||
|
self._device_type = DeviceType.LightStrip
|
||||||
|
elif "dimmer_calibration" in self._components:
|
||||||
|
self._device_type = DeviceType.Dimmer
|
||||||
|
elif "brightness" in self._components:
|
||||||
|
self._device_type = DeviceType.Bulb
|
||||||
|
elif "PLUG" in self.sys_info["type"]:
|
||||||
|
self._device_type = DeviceType.Plug
|
||||||
|
else:
|
||||||
|
_LOGGER.warning("Unknown device type, falling back to plug")
|
||||||
|
self._device_type = DeviceType.Plug
|
||||||
|
|
||||||
|
return self._device_type
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
"""Module for a TAPO Plug."""
|
|
||||||
import logging
|
|
||||||
from typing import Any, Dict, Optional
|
|
||||||
|
|
||||||
from ..device_type import DeviceType
|
|
||||||
from ..deviceconfig import DeviceConfig
|
|
||||||
from ..plug import Plug
|
|
||||||
from ..smartprotocol import SmartProtocol
|
|
||||||
from .smartdevice import SmartDevice
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class SmartPlug(SmartDevice, Plug):
|
|
||||||
"""Class to represent a TAPO Plug."""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
host: str,
|
|
||||||
*,
|
|
||||||
config: Optional[DeviceConfig] = None,
|
|
||||||
protocol: Optional[SmartProtocol] = None,
|
|
||||||
) -> None:
|
|
||||||
super().__init__(host=host, config=config, protocol=protocol)
|
|
||||||
self._device_type = DeviceType.Plug
|
|
||||||
|
|
||||||
@property
|
|
||||||
def state_information(self) -> Dict[str, Any]:
|
|
||||||
"""Return the key state information."""
|
|
||||||
return {
|
|
||||||
**super().state_information,
|
|
||||||
**{
|
|
||||||
"On since": self.on_since,
|
|
||||||
"auto_off_status": self._info.get("auto_off_status"),
|
|
||||||
"auto_off_remain_time": self._info.get("auto_off_remain_time"),
|
|
||||||
},
|
|
||||||
}
|
|
@ -20,7 +20,7 @@ from kasa import (
|
|||||||
)
|
)
|
||||||
from kasa.iot import IotBulb, IotDimmer, IotLightStrip, IotPlug, IotStrip
|
from kasa.iot import IotBulb, IotDimmer, IotLightStrip, IotPlug, IotStrip
|
||||||
from kasa.protocol import BaseTransport
|
from kasa.protocol import BaseTransport
|
||||||
from kasa.smart import SmartBulb, SmartPlug
|
from kasa.smart import SmartBulb, SmartDevice
|
||||||
from kasa.xortransport import XorEncryption
|
from kasa.xortransport import XorEncryption
|
||||||
|
|
||||||
from .fakeprotocol_iot import FakeIotProtocol
|
from .fakeprotocol_iot import FakeIotProtocol
|
||||||
@ -108,7 +108,6 @@ PLUGS_SMART = {
|
|||||||
"EP25",
|
"EP25",
|
||||||
"KS205",
|
"KS205",
|
||||||
"P125M",
|
"P125M",
|
||||||
"P135",
|
|
||||||
"S505",
|
"S505",
|
||||||
"TP15",
|
"TP15",
|
||||||
}
|
}
|
||||||
@ -121,7 +120,7 @@ STRIPS_SMART = {"P300", "TP25"}
|
|||||||
STRIPS = {*STRIPS_IOT, *STRIPS_SMART}
|
STRIPS = {*STRIPS_IOT, *STRIPS_SMART}
|
||||||
|
|
||||||
DIMMERS_IOT = {"ES20M", "HS220", "KS220M", "KS230", "KP405"}
|
DIMMERS_IOT = {"ES20M", "HS220", "KS220M", "KS230", "KP405"}
|
||||||
DIMMERS_SMART = {"S500D"}
|
DIMMERS_SMART = {"S500D", "P135"}
|
||||||
DIMMERS = {
|
DIMMERS = {
|
||||||
*DIMMERS_IOT,
|
*DIMMERS_IOT,
|
||||||
*DIMMERS_SMART,
|
*DIMMERS_SMART,
|
||||||
@ -346,7 +345,7 @@ def device_for_file(model, protocol):
|
|||||||
if protocol == "SMART":
|
if protocol == "SMART":
|
||||||
for d in PLUGS_SMART:
|
for d in PLUGS_SMART:
|
||||||
if d in model:
|
if d in model:
|
||||||
return SmartPlug
|
return SmartDevice
|
||||||
for d in BULBS_SMART:
|
for d in BULBS_SMART:
|
||||||
if d in model:
|
if d in model:
|
||||||
return SmartBulb
|
return SmartBulb
|
||||||
@ -355,7 +354,7 @@ def device_for_file(model, protocol):
|
|||||||
return SmartBulb
|
return SmartBulb
|
||||||
for d in STRIPS_SMART:
|
for d in STRIPS_SMART:
|
||||||
if d in model:
|
if d in model:
|
||||||
return SmartPlug
|
return SmartDevice
|
||||||
else:
|
else:
|
||||||
for d in STRIPS_IOT:
|
for d in STRIPS_IOT:
|
||||||
if d in model:
|
if d in model:
|
||||||
|
@ -37,9 +37,6 @@ async def test_led(dev):
|
|||||||
@plug_smart
|
@plug_smart
|
||||||
async def test_plug_device_info(dev):
|
async def test_plug_device_info(dev):
|
||||||
assert dev._info is not None
|
assert dev._info is not None
|
||||||
# PLUG_SCHEMA(dev.sys_info)
|
|
||||||
|
|
||||||
assert dev.model is not None
|
assert dev.model is not None
|
||||||
|
|
||||||
assert dev.device_type == DeviceType.Plug or dev.device_type == DeviceType.Strip
|
assert dev.device_type == DeviceType.Plug or dev.device_type == DeviceType.Strip
|
||||||
# assert dev.is_plug or dev.is_strip
|
|
||||||
|
@ -22,16 +22,21 @@ from voluptuous import (
|
|||||||
|
|
||||||
import kasa
|
import kasa
|
||||||
from kasa import Credentials, Device, DeviceConfig, KasaException
|
from kasa import Credentials, Device, DeviceConfig, KasaException
|
||||||
|
from kasa.device_type import DeviceType
|
||||||
from kasa.exceptions import SmartErrorCode
|
from kasa.exceptions import SmartErrorCode
|
||||||
from kasa.iot import IotDevice
|
from kasa.iot import IotDevice
|
||||||
from kasa.smart import SmartChildDevice, SmartDevice
|
from kasa.smart import SmartChildDevice, SmartDevice
|
||||||
|
|
||||||
from .conftest import (
|
from .conftest import (
|
||||||
|
bulb,
|
||||||
device_iot,
|
device_iot,
|
||||||
device_smart,
|
device_smart,
|
||||||
|
dimmer,
|
||||||
handle_turn_on,
|
handle_turn_on,
|
||||||
has_emeter_iot,
|
has_emeter_iot,
|
||||||
|
lightstrip,
|
||||||
no_emeter_iot,
|
no_emeter_iot,
|
||||||
|
plug,
|
||||||
turn_on,
|
turn_on,
|
||||||
)
|
)
|
||||||
from .fakeprotocol_iot import FakeIotProtocol
|
from .fakeprotocol_iot import FakeIotProtocol
|
||||||
@ -416,3 +421,25 @@ SYSINFO_SCHEMA = Schema(
|
|||||||
},
|
},
|
||||||
extra=REMOVE_EXTRA,
|
extra=REMOVE_EXTRA,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dimmer
|
||||||
|
def test_device_type_dimmer(dev):
|
||||||
|
assert dev.device_type == DeviceType.Dimmer
|
||||||
|
|
||||||
|
|
||||||
|
@bulb
|
||||||
|
def test_device_type_bulb(dev):
|
||||||
|
if dev.is_light_strip:
|
||||||
|
pytest.skip("bulb has also lightstrips to test the api")
|
||||||
|
assert dev.device_type == DeviceType.Bulb
|
||||||
|
|
||||||
|
|
||||||
|
@plug
|
||||||
|
def test_device_type_plug(dev):
|
||||||
|
assert dev.device_type == DeviceType.Plug
|
||||||
|
|
||||||
|
|
||||||
|
@lightstrip
|
||||||
|
def test_device_type_lightstrip(dev):
|
||||||
|
assert dev.device_type == DeviceType.LightStrip
|
||||||
|
Loading…
x
Reference in New Issue
Block a user