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

Skip to content

Rename bulb interface to light and move fan and light interface to interfaces #910

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 6 commits into from
May 11, 2024
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
10 changes: 5 additions & 5 deletions kasa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from typing import TYPE_CHECKING
from warnings import warn

from kasa.bulb import Bulb, BulbPreset
from kasa.credentials import Credentials
from kasa.device import Device
from kasa.device_type import DeviceType
Expand All @@ -36,6 +35,7 @@
UnsupportedDeviceError,
)
from kasa.feature import Feature
from kasa.interfaces.light import Light, LightPreset
from kasa.iotprotocol import (
IotProtocol,
_deprecated_TPLinkSmartHomeProtocol, # noqa: F401
Expand All @@ -52,14 +52,14 @@
"BaseProtocol",
"IotProtocol",
"SmartProtocol",
"BulbPreset",
"LightPreset",
"TurnOnBehaviors",
"TurnOnBehavior",
"DeviceType",
"Feature",
"EmeterStatus",
"Device",
"Bulb",
"Light",
"Plug",
"Module",
"KasaException",
Expand All @@ -84,7 +84,7 @@
"SmartLightStrip": iot.IotLightStrip,
"SmartStrip": iot.IotStrip,
"SmartDimmer": iot.IotDimmer,
"SmartBulbPreset": BulbPreset,
"SmartBulbPreset": LightPreset,
}
deprecated_exceptions = {
"SmartDeviceException": KasaException,
Expand Down Expand Up @@ -124,7 +124,7 @@ def __getattr__(name):
SmartLightStrip = iot.IotLightStrip
SmartStrip = iot.IotStrip
SmartDimmer = iot.IotDimmer
SmartBulbPreset = BulbPreset
SmartBulbPreset = LightPreset

SmartDeviceException = KasaException
UnsupportedDeviceException = UnsupportedDeviceError
Expand Down
6 changes: 3 additions & 3 deletions kasa/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

from kasa import (
AuthenticationError,
Bulb,
ConnectionType,
Credentials,
Device,
Expand All @@ -28,6 +27,7 @@
EncryptType,
Feature,
KasaException,
Light,
UnsupportedDeviceError,
)
from kasa.discover import DiscoveryResult
Expand Down Expand Up @@ -859,7 +859,7 @@ async def usage(dev: Device, year, month, erase):
@click.argument("brightness", type=click.IntRange(0, 100), default=None, required=False)
@click.option("--transition", type=int, required=False)
@pass_dev
async def brightness(dev: Bulb, brightness: int, transition: int):
async def brightness(dev: Light, brightness: int, transition: int):
"""Get or set brightness."""
if not dev.is_dimmable:
echo("This device does not support brightness.")
Expand All @@ -879,7 +879,7 @@ async def brightness(dev: Bulb, brightness: int, transition: int):
)
@click.option("--transition", type=int, required=False)
@pass_dev
async def temperature(dev: Bulb, temperature: int, transition: int):
async def temperature(dev: Light, temperature: int, transition: int):
"""Get or set color temperature."""
if not dev.is_variable_color_temp:
echo("Device does not support color temperature")
Expand Down
14 changes: 14 additions & 0 deletions kasa/interfaces/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Package for interfaces."""

from .fan import Fan
from .led import Led
from .light import Light, LightPreset
from .lighteffect import LightEffect

__all__ = [
"Fan",
"Led",
"Light",
"LightEffect",
"LightPreset",
]
2 changes: 1 addition & 1 deletion kasa/fan.py → kasa/interfaces/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from abc import ABC, abstractmethod

from .device import Device
from ..device import Device


class Fan(Device, ABC):
Expand Down
12 changes: 6 additions & 6 deletions kasa/bulb.py → kasa/interfaces/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from pydantic.v1 import BaseModel

from .device import Device
from ..device import Device


class ColorTempRange(NamedTuple):
Expand All @@ -25,8 +25,8 @@ class HSV(NamedTuple):
value: int


class BulbPreset(BaseModel):
"""Bulb configuration preset."""
class LightPreset(BaseModel):
"""Light configuration preset."""

index: int
brightness: int
Expand All @@ -42,8 +42,8 @@ class BulbPreset(BaseModel):
mode: Optional[int] # noqa: UP007


class Bulb(Device, ABC):
"""Base class for TP-Link Bulb."""
class Light(Device, ABC):
"""Base class for TP-Link Light."""

def _raise_for_invalid_brightness(self, value):
if not isinstance(value, int) or not (0 <= value <= 100):
Expand Down Expand Up @@ -135,5 +135,5 @@ async def set_brightness(

@property
@abstractmethod
def presets(self) -> list[BulbPreset]:
def presets(self) -> list[LightPreset]:
"""Return a list of available bulb setting presets."""
14 changes: 7 additions & 7 deletions kasa/iot/iotbulb.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@

from pydantic.v1 import BaseModel, Field, root_validator

from ..bulb import HSV, Bulb, BulbPreset, ColorTempRange
from ..device_type import DeviceType
from ..deviceconfig import DeviceConfig
from ..feature import Feature
from ..interfaces.light import HSV, ColorTempRange, Light, LightPreset
from ..module import Module
from ..protocol import BaseProtocol
from .iotdevice import IotDevice, KasaException, requires_update
Expand Down Expand Up @@ -88,7 +88,7 @@ class TurnOnBehaviors(BaseModel):
_LOGGER = logging.getLogger(__name__)


class IotBulb(IotDevice, Bulb):
class IotBulb(IotDevice, Light):
r"""Representation of a TP-Link Smart Bulb.

To initialize, you have to await :func:`update()` at least once.
Expand Down Expand Up @@ -170,9 +170,9 @@ class IotBulb(IotDevice, Bulb):
Bulb configuration presets can be accessed using the :func:`presets` property:

>>> bulb.presets
[BulbPreset(index=0, brightness=50, hue=0, saturation=0, color_temp=2700, custom=None, id=None, mode=None), BulbPreset(index=1, brightness=100, hue=0, saturation=75, color_temp=0, custom=None, id=None, mode=None), BulbPreset(index=2, brightness=100, hue=120, saturation=75, color_temp=0, custom=None, id=None, mode=None), BulbPreset(index=3, brightness=100, hue=240, saturation=75, color_temp=0, custom=None, id=None, mode=None)]
[LightPreset(index=0, brightness=50, hue=0, saturation=0, color_temp=2700, custom=None, id=None, mode=None), LightPreset(index=1, brightness=100, hue=0, saturation=75, color_temp=0, custom=None, id=None, mode=None), LightPreset(index=2, brightness=100, hue=120, saturation=75, color_temp=0, custom=None, id=None, mode=None), LightPreset(index=3, brightness=100, hue=240, saturation=75, color_temp=0, custom=None, id=None, mode=None)]

To modify an existing preset, pass :class:`~kasa.smartbulb.SmartBulbPreset`
To modify an existing preset, pass :class:`~kasa.smartbulb.LightPreset`
instance to :func:`save_preset` method:

>>> preset = bulb.presets[0]
Expand Down Expand Up @@ -523,11 +523,11 @@ async def set_alias(self, alias: str) -> None:

@property # type: ignore
@requires_update
def presets(self) -> list[BulbPreset]:
def presets(self) -> list[LightPreset]:
"""Return a list of available bulb setting presets."""
return [BulbPreset(**vals) for vals in self.sys_info["preferred_state"]]
return [LightPreset(**vals) for vals in self.sys_info["preferred_state"]]

async def save_preset(self, preset: BulbPreset):
async def save_preset(self, preset: LightPreset):
"""Save a setting preset.

You can either construct a preset object manually, or pass an existing one
Expand Down
2 changes: 1 addition & 1 deletion kasa/smart/modules/color.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

from typing import TYPE_CHECKING

from ...bulb import HSV
from ...feature import Feature
from ...interfaces.light import HSV
from ..smartmodule import SmartModule

if TYPE_CHECKING:
Expand Down
2 changes: 1 addition & 1 deletion kasa/smart/modules/colortemperature.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import logging
from typing import TYPE_CHECKING

from ...bulb import ColorTempRange
from ...feature import Feature
from ...interfaces.light import ColorTempRange
from ..smartmodule import SmartModule

if TYPE_CHECKING:
Expand Down
8 changes: 4 additions & 4 deletions kasa/smart/smartdevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
from typing import TYPE_CHECKING, Any, Mapping, Sequence, cast

from ..aestransport import AesTransport
from ..bulb import HSV, Bulb, BulbPreset, ColorTempRange
from ..device import Device, WifiNetwork
from ..device_type import DeviceType
from ..deviceconfig import DeviceConfig
from ..emeterstatus import EmeterStatus
from ..exceptions import AuthenticationError, DeviceError, KasaException, SmartErrorCode
from ..fan import Fan
from ..feature import Feature
from ..interfaces.fan import Fan
from ..interfaces.light import HSV, ColorTempRange, Light, LightPreset
from ..module import Module
from ..modulemapping import ModuleMapping, ModuleName
from ..smartprotocol import SmartProtocol
Expand All @@ -39,7 +39,7 @@

# Device must go last as the other interfaces also inherit Device
# and python needs a consistent method resolution order.
class SmartDevice(Bulb, Fan, Device):
class SmartDevice(Light, Fan, Device):
"""Base class to represent a SMART protocol based device."""

def __init__(
Expand Down Expand Up @@ -766,7 +766,7 @@ async def set_brightness(
return await self.modules[Module.Brightness].set_brightness(brightness)

@property
def presets(self) -> list[BulbPreset]:
def presets(self) -> list[LightPreset]:
"""Return a list of available bulb setting presets."""
return []

Expand Down
32 changes: 16 additions & 16 deletions kasa/tests/test_bulb.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Schema,
)

from kasa import Bulb, BulbPreset, Device, DeviceType, KasaException
from kasa import Device, DeviceType, KasaException, Light, LightPreset
from kasa.iot import IotBulb, IotDimmer
from kasa.smart import SmartDevice

Expand Down Expand Up @@ -65,7 +65,7 @@ async def test_get_light_state(dev: IotBulb):
@color_bulb
@turn_on
async def test_hsv(dev: Device, turn_on):
assert isinstance(dev, Bulb)
assert isinstance(dev, Light)
await handle_turn_on(dev, turn_on)
assert dev.is_color

Expand Down Expand Up @@ -96,7 +96,7 @@ async def test_set_hsv_transition(dev: IotBulb, mocker):

@color_bulb
@turn_on
async def test_invalid_hsv(dev: Bulb, turn_on):
async def test_invalid_hsv(dev: Light, turn_on):
await handle_turn_on(dev, turn_on)
assert dev.is_color

Expand All @@ -116,13 +116,13 @@ async def test_invalid_hsv(dev: Bulb, turn_on):
@color_bulb
@pytest.mark.skip("requires color feature")
async def test_color_state_information(dev: Device):
assert isinstance(dev, Bulb)
assert isinstance(dev, Light)
assert "HSV" in dev.state_information
assert dev.state_information["HSV"] == dev.hsv


@non_color_bulb
async def test_hsv_on_non_color(dev: Bulb):
async def test_hsv_on_non_color(dev: Light):
assert not dev.is_color

with pytest.raises(KasaException):
Expand All @@ -134,15 +134,15 @@ 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: Device):
assert isinstance(dev, Bulb)
assert isinstance(dev, Light)
assert "Color temperature" in dev.state_information
assert dev.state_information["Color temperature"] == dev.color_temp


@variable_temp
@turn_on
async def test_try_set_colortemp(dev: Device, turn_on):
assert isinstance(dev, Bulb)
assert isinstance(dev, Light)
await handle_turn_on(dev, turn_on)
await dev.set_color_temp(2700)
await dev.update()
Expand Down Expand Up @@ -171,15 +171,15 @@ async def test_smart_temp_range(dev: SmartDevice):


@variable_temp
async def test_out_of_range_temperature(dev: Bulb):
async def test_out_of_range_temperature(dev: Light):
with pytest.raises(ValueError):
await dev.set_color_temp(1000)
with pytest.raises(ValueError):
await dev.set_color_temp(10000)


@non_variable_temp
async def test_non_variable_temp(dev: Bulb):
async def test_non_variable_temp(dev: Light):
with pytest.raises(KasaException):
await dev.set_color_temp(2700)

Expand All @@ -193,7 +193,7 @@ async def test_non_variable_temp(dev: Bulb):
@dimmable
@turn_on
async def test_dimmable_brightness(dev: Device, turn_on):
assert isinstance(dev, (Bulb, IotDimmer))
assert isinstance(dev, (Light, IotDimmer))
await handle_turn_on(dev, turn_on)
assert dev.is_dimmable

Expand Down Expand Up @@ -230,7 +230,7 @@ async def test_dimmable_brightness_transition(dev: IotBulb, mocker):


@dimmable
async def test_invalid_brightness(dev: Bulb):
async def test_invalid_brightness(dev: Light):
assert dev.is_dimmable

with pytest.raises(ValueError):
Expand All @@ -241,7 +241,7 @@ async def test_invalid_brightness(dev: Bulb):


@non_dimmable
async def test_non_dimmable(dev: Bulb):
async def test_non_dimmable(dev: Light):
assert not dev.is_dimmable

with pytest.raises(KasaException):
Expand Down Expand Up @@ -291,7 +291,7 @@ async def test_modify_preset(dev: IotBulb, mocker):
"saturation": 0,
"color_temp": 0,
}
preset = BulbPreset(**data)
preset = LightPreset(**data)

assert preset.index == 0
assert preset.brightness == 10
Expand All @@ -305,7 +305,7 @@ async def test_modify_preset(dev: IotBulb, mocker):

with pytest.raises(KasaException):
await dev.save_preset(
BulbPreset(index=5, hue=0, brightness=0, saturation=0, color_temp=0)
LightPreset(index=5, hue=0, brightness=0, saturation=0, color_temp=0)
)


Expand All @@ -314,11 +314,11 @@ async def test_modify_preset(dev: IotBulb, mocker):
("preset", "payload"),
[
(
BulbPreset(index=0, hue=0, brightness=1, saturation=0),
LightPreset(index=0, hue=0, brightness=1, saturation=0),
{"index": 0, "hue": 0, "brightness": 1, "saturation": 0},
),
(
BulbPreset(index=0, brightness=1, id="testid", mode=2, custom=0),
LightPreset(index=0, brightness=1, id="testid", mode=2, custom=0),
{"index": 0, "brightness": 1, "id": "testid", "mode": 2, "custom": 0},
),
],
Expand Down
1 change: 1 addition & 0 deletions kasa/tests/test_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def _get_subclasses(of_class):
inspect.isclass(obj)
and issubclass(obj, of_class)
and module.__package__ != "kasa"
and module.__package__ != "kasa.interfaces"
):
subclasses.add((module.__package__ + "." + name, obj))
return subclasses
Expand Down