mirror of
https://github.com/python-kasa/python-kasa.git
synced 2026-07-08 14:52:03 +00:00
docs: modernize docstrings across the repository (#1682)
Comprehensive docstring cleanup across the repository — fix Sphinx cross-references, Python REPL continuation syntax, stale class names, and modernize the IotBulb docstring to use the `Module.Light`/`Module.LightPreset` interface.
This commit is contained in:
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
>>> devices = await Discover.discover(username="user@example.com", password="great_password")
|
>>> devices = await Discover.discover(username="user@example.com", password="great_password")
|
||||||
>>> for dev in devices.values():
|
>>> for dev in devices.values():
|
||||||
>>> await dev.update()
|
... await dev.update()
|
||||||
>>> print(dev.host)
|
... print(dev.host)
|
||||||
127.0.0.1
|
127.0.0.1
|
||||||
127.0.0.2
|
127.0.0.2
|
||||||
127.0.0.3
|
127.0.0.3
|
||||||
@@ -56,20 +56,23 @@ True
|
|||||||
>>> light.has_feature("hsv")
|
>>> light.has_feature("hsv")
|
||||||
True
|
True
|
||||||
>>> if light.has_feature("hsv"):
|
>>> if light.has_feature("hsv"):
|
||||||
>>> print(light.hsv)
|
... print(light.hsv)
|
||||||
HSV(hue=0, saturation=100, value=50)
|
HSV(hue=0, saturation=100, value=50)
|
||||||
|
|
||||||
You can test if a module is supported by using `get` to access it.
|
You can test if a module is supported by using `get` to access it.
|
||||||
|
|
||||||
>>> if effect := dev.modules.get(Module.LightEffect):
|
>>> if effect := dev.modules.get(Module.LightEffect):
|
||||||
>>> print(effect.effect)
|
... print(effect.effect)
|
||||||
>>> print(effect.effect_list)
|
... print(effect.effect_list)
|
||||||
>>> if effect := dev.modules.get(Module.LightEffect):
|
|
||||||
>>> await effect.set_effect("Party")
|
|
||||||
>>> await dev.update()
|
|
||||||
>>> print(effect.effect)
|
|
||||||
Off
|
Off
|
||||||
['Off', 'Party', 'Relax']
|
['Off', 'Party', 'Relax']
|
||||||
|
|
||||||
|
You can then interact with the module:
|
||||||
|
|
||||||
|
>>> if effect := dev.modules.get(Module.LightEffect):
|
||||||
|
... _ = await effect.set_effect("Party")
|
||||||
|
... await dev.update()
|
||||||
|
... print(effect.effect)
|
||||||
Party
|
Party
|
||||||
|
|
||||||
Individual pieces of functionality are also exposed via features which you can access via :attr:`~kasa.Device.features` and will only be present if they are supported.
|
Individual pieces of functionality are also exposed via features which you can access via :attr:`~kasa.Device.features` and will only be present if they are supported.
|
||||||
@@ -83,14 +86,14 @@ The advantage of features is that they have a simple common interface of `id`, `
|
|||||||
They are useful if you want write code that dynamically adapts as new features are added to the API.
|
They are useful if you want write code that dynamically adapts as new features are added to the API.
|
||||||
|
|
||||||
>>> if auto_update := dev.features.get("auto_update_enabled"):
|
>>> if auto_update := dev.features.get("auto_update_enabled"):
|
||||||
>>> print(auto_update.value)
|
... print(auto_update.value)
|
||||||
False
|
False
|
||||||
>>> if auto_update:
|
>>> if auto_update:
|
||||||
>>> await auto_update.set_value(True)
|
... _ = await auto_update.set_value(True)
|
||||||
>>> await dev.update()
|
... await dev.update()
|
||||||
>>> print(auto_update.value)
|
... print(auto_update.value)
|
||||||
True
|
True
|
||||||
>>> for feat in dev.features.values():
|
>>> for feat in dev.features.values():
|
||||||
>>> print(f"{feat.name}: {feat.value}")
|
... print(f"{feat.name}: {feat.value}")
|
||||||
Device ID: 0000000000000000000000000000000000000000\nState: True\nSignal Level: 2\nRSSI: -52\nSSID: #MASKED_SSID#\nReboot: <Action>\nDevice time: 2024-02-23 02:40:15+01:00\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: <Action>\nLight effect: Party\nLight preset: Light preset 1\nSmooth transition on: 2\nSmooth transition off: 2\nOverheated: False
|
Device ID: 0000000000000000000000000000000000000000\nState: True\nSignal Level: 2\nRSSI: -52\nSSID: #MASKED_SSID#\nReboot: <Action>\nDevice time: 2024-02-23 02:40:15+01:00\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: <Action>\nLight effect: Party\nLight preset: Light preset 1\nSmooth transition on: 2\nSmooth transition off: 2\nOverheated: False
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ Once you have a device via :ref:`Discovery <discover_target>` or
|
|||||||
>>> from kasa import Discover
|
>>> from kasa import Discover
|
||||||
>>>
|
>>>
|
||||||
>>> dev = await Discover.discover_single(
|
>>> dev = await Discover.discover_single(
|
||||||
>>> "127.0.0.2",
|
... "127.0.0.2",
|
||||||
>>> username="user@example.com",
|
... username="user@example.com",
|
||||||
>>> password="great_password"
|
... password="great_password"
|
||||||
>>> )
|
... )
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
Most devices can be turned on and off
|
Most devices can be turned on and off
|
||||||
@@ -46,7 +46,7 @@ Devices support different functionality that are exposed via
|
|||||||
:ref:`modules <module_target>` that you can access via :attr:`~kasa.Device.modules`:
|
:ref:`modules <module_target>` that you can access via :attr:`~kasa.Device.modules`:
|
||||||
|
|
||||||
>>> for module_name in dev.modules:
|
>>> for module_name in dev.modules:
|
||||||
>>> print(module_name)
|
... print(module_name)
|
||||||
homekit
|
homekit
|
||||||
Energy
|
Energy
|
||||||
schedule
|
schedule
|
||||||
@@ -81,7 +81,7 @@ They are useful if you want write code that dynamically adapts as new features a
|
|||||||
added to the API.
|
added to the API.
|
||||||
|
|
||||||
>>> for feature_name in dev.features:
|
>>> for feature_name in dev.features:
|
||||||
>>> print(feature_name)
|
... print(feature_name)
|
||||||
state
|
state
|
||||||
rssi
|
rssi
|
||||||
on_since
|
on_since
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ Discovery returns a list of discovered devices:
|
|||||||
|
|
||||||
>>> from kasa import Discover, Device
|
>>> from kasa import Discover, Device
|
||||||
>>> device = await Discover.discover_single(
|
>>> device = await Discover.discover_single(
|
||||||
>>> "127.0.0.3",
|
... "127.0.0.3",
|
||||||
>>> username="user@example.com",
|
... username="user@example.com",
|
||||||
>>> password="great_password",
|
... password="great_password",
|
||||||
>>> )
|
... )
|
||||||
>>> print(device.alias) # Alias is None because update() has not been called
|
>>> print(device.alias) # Alias is None because update() has not been called
|
||||||
None
|
None
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
"""Discover TPLink Smart Home devices.
|
"""Discover TPLink Smart Home devices.
|
||||||
|
|
||||||
The main entry point for this library is :func:`Discover.discover()`,
|
The main entry point for this library is :meth:`Discover.discover()`,
|
||||||
which returns a dictionary of the found devices. The key is the IP address
|
which returns a dictionary of the found devices. The key is the IP address
|
||||||
of the device and the value contains ready-to-use, SmartDevice-derived
|
of the device and the value contains ready-to-use, SmartDevice-derived
|
||||||
device object.
|
device object.
|
||||||
|
|
||||||
:func:`discover_single()` can be used to initialize a single device given its
|
:meth:`discover_single()` can be used to initialize a single device given its
|
||||||
IP address. If the :class:`DeviceConfig` of the device is already known,
|
IP address. If the :class:`DeviceConfig` of the device is already known,
|
||||||
you can initialize the corresponding device class directly without discovery.
|
you can initialize the corresponding device class directly without discovery.
|
||||||
|
|
||||||
@@ -27,9 +27,9 @@ Discovery returns a dict of {ip: discovered devices}:
|
|||||||
You can pass username and password for devices requiring authentication
|
You can pass username and password for devices requiring authentication
|
||||||
|
|
||||||
>>> devices = await Discover.discover(
|
>>> devices = await Discover.discover(
|
||||||
>>> username="user@example.com",
|
... username="user@example.com",
|
||||||
>>> password="great_password",
|
... password="great_password",
|
||||||
>>> )
|
... )
|
||||||
>>> print(len(devices))
|
>>> print(len(devices))
|
||||||
6
|
6
|
||||||
|
|
||||||
@@ -61,8 +61,8 @@ None
|
|||||||
It is also possible to pass a coroutine to be executed for each found device:
|
It is also possible to pass a coroutine to be executed for each found device:
|
||||||
|
|
||||||
>>> async def print_dev_info(dev):
|
>>> async def print_dev_info(dev):
|
||||||
>>> await dev.update()
|
... await dev.update()
|
||||||
>>> print(f"Discovered {dev.alias} (model: {dev.model})")
|
... print(f"Discovered {dev.alias} (model: {dev.model})")
|
||||||
>>>
|
>>>
|
||||||
>>> devices = await Discover.discover(on_discovered=print_dev_info, credentials=creds)
|
>>> devices = await Discover.discover(on_discovered=print_dev_info, credentials=creds)
|
||||||
Discovered Bedroom Power Strip (model: KP303)
|
Discovered Bedroom Power Strip (model: KP303)
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ state, time, firmware.
|
|||||||
>>> from kasa import Discover, Module
|
>>> from kasa import Discover, Module
|
||||||
>>>
|
>>>
|
||||||
>>> dev = await Discover.discover_single(
|
>>> dev = await Discover.discover_single(
|
||||||
>>> "127.0.0.3",
|
... "127.0.0.3",
|
||||||
>>> username="user@example.com",
|
... username="user@example.com",
|
||||||
>>> password="great_password"
|
... password="great_password"
|
||||||
>>> )
|
... )
|
||||||
>>> await dev.update()
|
>>> await dev.update()
|
||||||
>>> print(dev.alias)
|
>>> print(dev.alias)
|
||||||
Living Room Bulb
|
Living Room Bulb
|
||||||
@@ -18,7 +18,7 @@ Features allow for instrospection and can be interacted with as new features are
|
|||||||
to the API:
|
to the API:
|
||||||
|
|
||||||
>>> for feature_id, feature in dev.features.items():
|
>>> for feature_id, feature in dev.features.items():
|
||||||
>>> print(f"{feature.name} ({feature_id}): {feature.value}")
|
... print(f"{feature.name} ({feature_id}): {feature.value}")
|
||||||
Device ID (device_id): 0000000000000000000000000000000000000000
|
Device ID (device_id): 0000000000000000000000000000000000000000
|
||||||
State (state): True
|
State (state): True
|
||||||
Signal Level (signal_level): 2
|
Signal Level (signal_level): 2
|
||||||
@@ -44,7 +44,7 @@ Overheated (overheated): False
|
|||||||
To see whether a device supports a feature, check for the existence of it:
|
To see whether a device supports a feature, check for the existence of it:
|
||||||
|
|
||||||
>>> if feature := dev.features.get("brightness"):
|
>>> if feature := dev.features.get("brightness"):
|
||||||
>>> print(feature.value)
|
... print(feature.value)
|
||||||
100
|
100
|
||||||
|
|
||||||
You can update the value of a feature
|
You can update the value of a feature
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ hubs.
|
|||||||
>>> from kasa import Discover, Module, LightState
|
>>> from kasa import Discover, Module, LightState
|
||||||
>>>
|
>>>
|
||||||
>>> dev = await Discover.discover_single(
|
>>> dev = await Discover.discover_single(
|
||||||
>>> "127.0.0.6",
|
... "127.0.0.6",
|
||||||
>>> username="user@example.com",
|
... username="user@example.com",
|
||||||
>>> password="great_password"
|
... password="great_password"
|
||||||
>>> )
|
... )
|
||||||
>>> await dev.update()
|
>>> await dev.update()
|
||||||
>>> print(dev.alias)
|
>>> print(dev.alias)
|
||||||
Tapo Hub
|
Tapo Hub
|
||||||
@@ -27,7 +27,7 @@ The hub will pair with all supported devices in pairing mode:
|
|||||||
'device_model': 'S200B', 'name': 'I01BU0tFRF9OQU1FIw===='}]
|
'device_model': 'S200B', 'name': 'I01BU0tFRF9OQU1FIw===='}]
|
||||||
|
|
||||||
>>> for child in dev.children:
|
>>> for child in dev.children:
|
||||||
>>> print(f"{child.device_id} - {child.model}")
|
... print(f"{child.device_id} - {child.model}")
|
||||||
SCRUBBED_CHILD_DEVICE_ID_1 - T310
|
SCRUBBED_CHILD_DEVICE_ID_1 - T310
|
||||||
SCRUBBED_CHILD_DEVICE_ID_2 - T315
|
SCRUBBED_CHILD_DEVICE_ID_2 - T315
|
||||||
SCRUBBED_CHILD_DEVICE_ID_3 - T110
|
SCRUBBED_CHILD_DEVICE_ID_3 - T110
|
||||||
@@ -38,7 +38,7 @@ Unpair with the child `device_id`:
|
|||||||
|
|
||||||
>>> await childsetup.unpair("SCRUBBED_CHILD_DEVICE_ID_4")
|
>>> await childsetup.unpair("SCRUBBED_CHILD_DEVICE_ID_4")
|
||||||
>>> for child in dev.children:
|
>>> for child in dev.children:
|
||||||
>>> print(f"{child.device_id} - {child.model}")
|
... print(f"{child.device_id} - {child.model}")
|
||||||
SCRUBBED_CHILD_DEVICE_ID_1 - T310
|
SCRUBBED_CHILD_DEVICE_ID_1 - T310
|
||||||
SCRUBBED_CHILD_DEVICE_ID_2 - T315
|
SCRUBBED_CHILD_DEVICE_ID_2 - T315
|
||||||
SCRUBBED_CHILD_DEVICE_ID_3 - T110
|
SCRUBBED_CHILD_DEVICE_ID_3 - T110
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
>>> from kasa import Discover, Module
|
>>> from kasa import Discover, Module
|
||||||
>>>
|
>>>
|
||||||
>>> dev = await Discover.discover_single(
|
>>> dev = await Discover.discover_single(
|
||||||
>>> "127.0.0.3",
|
... "127.0.0.3",
|
||||||
>>> username="user@example.com",
|
... username="user@example.com",
|
||||||
>>> password="great_password"
|
... password="great_password"
|
||||||
>>> )
|
... )
|
||||||
>>> await dev.update()
|
>>> await dev.update()
|
||||||
>>> print(dev.alias)
|
>>> print(dev.alias)
|
||||||
Living Room Bulb
|
Living Room Bulb
|
||||||
@@ -44,7 +44,7 @@ All known bulbs support changing the brightness:
|
|||||||
Bulbs supporting color temperature can be queried for the supported range:
|
Bulbs supporting color temperature can be queried for the supported range:
|
||||||
|
|
||||||
>>> if color_temp_feature := light.get_feature("color_temp"):
|
>>> if color_temp_feature := light.get_feature("color_temp"):
|
||||||
>>> print(f"{color_temp_feature.minimum_value}, {color_temp_feature.maximum_value}")
|
... print(f"{color_temp_feature.minimum_value}, {color_temp_feature.maximum_value}")
|
||||||
2500, 6500
|
2500, 6500
|
||||||
>>> await light.set_color_temp(3000)
|
>>> await light.set_color_temp(3000)
|
||||||
>>> await dev.update()
|
>>> await dev.update()
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
>>> from kasa import Discover, Module, LightState
|
>>> from kasa import Discover, Module, LightState
|
||||||
>>>
|
>>>
|
||||||
>>> dev = await Discover.discover_single(
|
>>> dev = await Discover.discover_single(
|
||||||
>>> "127.0.0.3",
|
... "127.0.0.3",
|
||||||
>>> username="user@example.com",
|
... username="user@example.com",
|
||||||
>>> password="great_password"
|
... password="great_password"
|
||||||
>>> )
|
... )
|
||||||
>>> await dev.update()
|
>>> await dev.update()
|
||||||
>>> print(dev.alias)
|
>>> print(dev.alias)
|
||||||
Living Room Bulb
|
Living Room Bulb
|
||||||
@@ -32,8 +32,8 @@ Party
|
|||||||
If the device supports it you can set custom effects:
|
If the device supports it you can set custom effects:
|
||||||
|
|
||||||
>>> if light_effect.has_custom_effects:
|
>>> if light_effect.has_custom_effects:
|
||||||
>>> effect_list = { "brightness", 50 }
|
... effect_list = {"brightness": 50}
|
||||||
>>> await light_effect.set_custom_effect(effect_list)
|
... await light_effect.set_custom_effect(effect_list)
|
||||||
>>> light_effect.has_custom_effects # The device in this examples does not support \
|
>>> light_effect.has_custom_effects # The device in this examples does not support \
|
||||||
custom effects
|
custom effects
|
||||||
False
|
False
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
>>> from kasa import Discover, Module, LightState
|
>>> from kasa import Discover, Module, LightState
|
||||||
>>>
|
>>>
|
||||||
>>> dev = await Discover.discover_single(
|
>>> dev = await Discover.discover_single(
|
||||||
>>> "127.0.0.3",
|
... "127.0.0.3",
|
||||||
>>> username="user@example.com",
|
... username="user@example.com",
|
||||||
>>> password="great_password"
|
... password="great_password"
|
||||||
>>> )
|
... )
|
||||||
>>> await dev.update()
|
>>> await dev.update()
|
||||||
>>> print(dev.alias)
|
>>> print(dev.alias)
|
||||||
Living Room Bulb
|
Living Room Bulb
|
||||||
@@ -48,9 +48,9 @@ LightState(light_on=True, brightness=50, hue=0,\
|
|||||||
You can save a new preset state if the device supports it:
|
You can save a new preset state if the device supports it:
|
||||||
|
|
||||||
>>> if light_preset.has_save_preset:
|
>>> if light_preset.has_save_preset:
|
||||||
>>> new_preset_state = LightState(light_on=True, brightness=75, hue=0,\
|
... new_preset_state = LightState(light_on=True, brightness=75, hue=0,\
|
||||||
saturation=100, color_temp=2700, transition=None)
|
saturation=100, color_temp=2700, transition=None)
|
||||||
>>> await light_preset.save_preset("Light preset 1", new_preset_state)
|
... await light_preset.save_preset("Light preset 1", new_preset_state)
|
||||||
>>> await dev.update()
|
>>> await dev.update()
|
||||||
>>> light_preset.preset # Saving updates the preset state for the preset, it does not \
|
>>> light_preset.preset # Saving updates the preset state for the preset, it does not \
|
||||||
set the preset
|
set the preset
|
||||||
|
|||||||
@@ -102,12 +102,12 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
class IotBulb(IotDevice):
|
class IotBulb(IotDevice):
|
||||||
r"""Representation of a TP-Link Smart Bulb.
|
r"""Representation of a TP-Link Smart Bulb.
|
||||||
|
|
||||||
To initialize, you have to await :func:`update()` at least once.
|
To initialize, you have to await :meth:`update()` at least once.
|
||||||
This will allow accessing the properties using the exposed properties.
|
This will allow accessing the properties using the exposed properties.
|
||||||
|
|
||||||
All changes to the device are done using awaitable methods,
|
All changes to the device are done using awaitable methods,
|
||||||
which will not change the cached values,
|
which will not change the cached values,
|
||||||
so you must await :func:`update()` to fetch updates values from the device.
|
so you must await :meth:`update()` to fetch updated values from the device.
|
||||||
|
|
||||||
Errors reported by the device are raised as
|
Errors reported by the device are raised as
|
||||||
:class:`KasaException <kasa.exceptions.KasaException>`,
|
:class:`KasaException <kasa.exceptions.KasaException>`,
|
||||||
@@ -118,7 +118,7 @@ class IotBulb(IotDevice):
|
|||||||
>>> bulb = IotBulb("127.0.0.1")
|
>>> bulb = IotBulb("127.0.0.1")
|
||||||
>>> asyncio.run(bulb.update())
|
>>> asyncio.run(bulb.update())
|
||||||
>>> print(bulb.alias)
|
>>> print(bulb.alias)
|
||||||
Bulb2
|
Bedroom Bulb
|
||||||
|
|
||||||
Bulbs, like any other supported devices, can be turned on and off:
|
Bulbs, like any other supported devices, can be turned on and off:
|
||||||
|
|
||||||
@@ -128,72 +128,82 @@ class IotBulb(IotDevice):
|
|||||||
>>> print(bulb.is_on)
|
>>> print(bulb.is_on)
|
||||||
True
|
True
|
||||||
|
|
||||||
You can use the ``is_``-prefixed properties to check for supported features:
|
Get the light module to interact with light-specific features:
|
||||||
|
|
||||||
>>> bulb.is_dimmable
|
>>> light = bulb.modules[Module.Light]
|
||||||
|
|
||||||
|
You can use the :meth:`~kasa.module.Module.has_feature` method to check for supported light features:
|
||||||
|
|
||||||
|
>>> light.has_feature("brightness")
|
||||||
True
|
True
|
||||||
>>> bulb.is_color
|
>>> light.has_feature("hsv")
|
||||||
True
|
True
|
||||||
>>> bulb.is_variable_color_temp
|
>>> light.has_feature("color_temp")
|
||||||
True
|
True
|
||||||
|
|
||||||
All known bulbs support changing the brightness:
|
All known bulbs support changing the brightness:
|
||||||
|
|
||||||
>>> bulb.brightness
|
>>> light.brightness
|
||||||
30
|
30
|
||||||
>>> asyncio.run(bulb.set_brightness(50))
|
>>> asyncio.run(light.set_brightness(50))
|
||||||
>>> asyncio.run(bulb.update())
|
>>> asyncio.run(bulb.update())
|
||||||
>>> bulb.brightness
|
>>> light.brightness
|
||||||
50
|
50
|
||||||
|
|
||||||
Bulbs supporting color temperature can be queried for the supported range:
|
Bulbs supporting color temperature can be queried for the supported range:
|
||||||
|
|
||||||
>>> bulb.valid_temperature_range
|
>>> if color_temp_feature := light.get_feature("color_temp"):
|
||||||
ColorTempRange(min=2500, max=9000)
|
... print(
|
||||||
>>> asyncio.run(bulb.set_color_temp(3000))
|
... f"{color_temp_feature.minimum_value}, "
|
||||||
|
... f"{color_temp_feature.maximum_value}"
|
||||||
|
... )
|
||||||
|
2500, 9000
|
||||||
|
>>> asyncio.run(light.set_color_temp(3000))
|
||||||
>>> asyncio.run(bulb.update())
|
>>> asyncio.run(bulb.update())
|
||||||
>>> bulb.color_temp
|
>>> light.color_temp
|
||||||
3000
|
3000
|
||||||
|
|
||||||
Color bulbs can be adjusted by passing hue, saturation and value:
|
Color bulbs can be adjusted by passing hue, saturation and value:
|
||||||
|
|
||||||
>>> asyncio.run(bulb.set_hsv(180, 100, 80))
|
>>> asyncio.run(light.set_hsv(180, 100, 80))
|
||||||
>>> asyncio.run(bulb.update())
|
>>> asyncio.run(bulb.update())
|
||||||
>>> bulb.hsv
|
>>> light.hsv
|
||||||
HSV(hue=180, saturation=100, value=80)
|
HSV(hue=180, saturation=100, value=80)
|
||||||
|
|
||||||
If you don't want to use the default transitions,
|
If you don't want to use the default transitions,
|
||||||
you can pass `transition` in milliseconds.
|
you can pass `transition` in milliseconds.
|
||||||
All methods changing the state of the device support this parameter:
|
All methods changing the light state support this parameter:
|
||||||
|
|
||||||
* :func:`turn_on`
|
* :meth:`turn_on`
|
||||||
* :func:`turn_off`
|
* :meth:`turn_off`
|
||||||
* :func:`set_hsv`
|
* :meth:`set_hsv`
|
||||||
* :func:`set_color_temp`
|
* :meth:`set_color_temp`
|
||||||
* :func:`set_brightness`
|
* :meth:`set_brightness`
|
||||||
|
|
||||||
Light strips (e.g., KL420L5) do not support this feature,
|
Light strips (e.g., KL420L5) do not support this feature,
|
||||||
but silently ignore the parameter.
|
but silently ignore the parameter.
|
||||||
The following changes the brightness over a period of 10 seconds:
|
The following changes the brightness over a period of 10 seconds:
|
||||||
|
|
||||||
>>> asyncio.run(bulb.set_brightness(100, transition=10_000))
|
>>> asyncio.run(light.set_brightness(100, transition=10_000))
|
||||||
|
|
||||||
Bulb configuration presets can be accessed using the :func:`presets` property:
|
Bulb configuration presets can be accessed using the light preset module:
|
||||||
|
|
||||||
>>> [ preset.to_dict() for preset in bulb.presets }
|
>>> light_preset = bulb.modules[Module.LightPreset]
|
||||||
[{'brightness': 50, 'hue': 0, 'saturation': 0, 'color_temp': 2700, 'index': 0}, {'brightness': 100, 'hue': 0, 'saturation': 75, 'color_temp': 0, 'index': 1}, {'brightness': 100, 'hue': 120, 'saturation': 75, 'color_temp': 0, 'index': 2}, {'brightness': 100, 'hue': 240, 'saturation': 75, 'color_temp': 0, 'index': 3}]
|
>>> light_preset.preset_states_list[0]
|
||||||
|
IotLightPreset(light_on=None, brightness=50, hue=0, saturation=0, color_temp=2700, transition=None)
|
||||||
|
|
||||||
To modify an existing preset, pass :class:`~kasa.interfaces.light.LightPreset`
|
To modify an existing preset, update one of the entries in
|
||||||
instance to :func:`save_preset` method:
|
``preset_states_list`` and pass it to
|
||||||
|
:meth:`~kasa.interfaces.lightpreset.LightPreset.save_preset`:
|
||||||
|
|
||||||
>>> preset = bulb.presets[0]
|
>>> preset = light_preset.preset_states_list[0]
|
||||||
>>> preset.brightness
|
>>> preset.brightness
|
||||||
50
|
50
|
||||||
>>> preset.brightness = 100
|
>>> preset.brightness = 100
|
||||||
>>> asyncio.run(bulb.save_preset(preset))
|
>>> asyncio.run(light_preset.save_preset("Light preset 1", preset))
|
||||||
>>> asyncio.run(bulb.update())
|
>>> asyncio.run(bulb.update())
|
||||||
>>> bulb.presets[0].brightness
|
>>> light_preset.preset_states_list[0]
|
||||||
100
|
IotLightPreset(light_on=None, brightness=100, hue=0, saturation=0, color_temp=2700, transition=None)
|
||||||
|
|
||||||
""" # noqa: E501
|
""" # noqa: E501
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class IotDevice(Device):
|
|||||||
* :class:`IotDimmer`
|
* :class:`IotDimmer`
|
||||||
* :class:`IotLightStrip`
|
* :class:`IotLightStrip`
|
||||||
|
|
||||||
To initialize, you have to await :func:`update()` at least once.
|
To initialize, you have to await :meth:`update()` at least once.
|
||||||
This will allow accessing the properties using the exposed properties.
|
This will allow accessing the properties using the exposed properties.
|
||||||
|
|
||||||
All changes to the device are done using awaitable methods,
|
All changes to the device are done using awaitable methods,
|
||||||
|
|||||||
@@ -41,14 +41,14 @@ class IotDimmer(IotPlug):
|
|||||||
r"""Representation of a TP-Link Smart Dimmer.
|
r"""Representation of a TP-Link Smart Dimmer.
|
||||||
|
|
||||||
Dimmers work similarly to plugs, but provide also support for
|
Dimmers work similarly to plugs, but provide also support for
|
||||||
adjusting the brightness. This class extends :class:`SmartPlug` interface.
|
adjusting the brightness. This class extends :class:`IotPlug` interface.
|
||||||
|
|
||||||
To initialize, you have to await :func:`update()` at least once.
|
To initialize, you have to await :meth:`update()` at least once.
|
||||||
This will allow accessing the properties using the exposed properties.
|
This will allow accessing the properties using the exposed properties.
|
||||||
|
|
||||||
All changes to the device are done using awaitable methods,
|
All changes to the device are done using awaitable methods,
|
||||||
which will not change the cached values,
|
which will not change the cached values,
|
||||||
but you must await :func:`update()` separately.
|
but you must await :meth:`update()` separately.
|
||||||
|
|
||||||
Errors reported by the device are raised as :class:`KasaException`\s,
|
Errors reported by the device are raised as :class:`KasaException`\s,
|
||||||
and should be handled by the user of the library.
|
and should be handled by the user of the library.
|
||||||
@@ -65,7 +65,7 @@ class IotDimmer(IotPlug):
|
|||||||
>>> dimmer.brightness
|
>>> dimmer.brightness
|
||||||
50
|
50
|
||||||
|
|
||||||
Refer to :class:`SmartPlug` for the full API.
|
Refer to :class:`IotPlug` for the full API.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
DIMMER_SERVICE = "smartlife.iot.dimmer"
|
DIMMER_SERVICE = "smartlife.iot.dimmer"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class IotLightStrip(IotBulb):
|
|||||||
|
|
||||||
Light strips work similarly to bulbs, but use a different service for controlling,
|
Light strips work similarly to bulbs, but use a different service for controlling,
|
||||||
and expose some extra information (such as length and active effect).
|
and expose some extra information (such as length and active effect).
|
||||||
This class extends :class:`SmartBulb` interface.
|
This class extends :class:`IotBulb` interface.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
>>> import asyncio
|
>>> import asyncio
|
||||||
@@ -41,7 +41,7 @@ class IotLightStrip(IotBulb):
|
|||||||
feel free to find out how to control them and create a PR!
|
feel free to find out how to control them and create a PR!
|
||||||
|
|
||||||
|
|
||||||
See :class:`SmartBulb` for more examples.
|
See :class:`IotBulb` for more examples.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
LIGHT_SERVICE = "smartlife.iot.lightStrip"
|
LIGHT_SERVICE = "smartlife.iot.lightStrip"
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
class IotPlug(IotDevice):
|
class IotPlug(IotDevice):
|
||||||
r"""Representation of a TP-Link Smart Plug.
|
r"""Representation of a TP-Link Smart Plug.
|
||||||
|
|
||||||
To initialize, you have to await :func:`update()` at least once.
|
To initialize, you have to await :meth:`update()` at least once.
|
||||||
This will allow accessing the properties using the exposed properties.
|
This will allow accessing the properties using the exposed properties.
|
||||||
|
|
||||||
All changes to the device are done using awaitable methods,
|
All changes to the device are done using awaitable methods,
|
||||||
which will not change the cached values,
|
which will not change the cached values,
|
||||||
but you must await :func:`update()` separately.
|
but you must await :meth:`update()` separately.
|
||||||
|
|
||||||
Errors reported by the device are raised as :class:`KasaException`\s,
|
Errors reported by the device are raised as :class:`KasaException`\s,
|
||||||
and should be handled by the user of the library.
|
and should be handled by the user of the library.
|
||||||
|
|||||||
@@ -53,14 +53,14 @@ class IotStrip(IotDevice):
|
|||||||
|
|
||||||
A strip consists of the parent device and its children.
|
A strip consists of the parent device and its children.
|
||||||
All methods of the parent act on all children, while the child devices
|
All methods of the parent act on all children, while the child devices
|
||||||
share the common API with the :class:`SmartPlug` class.
|
share the common API with the :class:`IotPlug` class.
|
||||||
|
|
||||||
To initialize, you have to await :func:`update()` at least once.
|
To initialize, you have to await :meth:`update()` at least once.
|
||||||
This will allow accessing the properties using the exposed properties.
|
This will allow accessing the properties using the exposed properties.
|
||||||
|
|
||||||
All changes to the device are done using awaitable methods,
|
All changes to the device are done using awaitable methods,
|
||||||
which will not change the cached values,
|
which will not change the cached values,
|
||||||
but you must await :func:`update()` separately.
|
but you must await :meth:`update()` separately.
|
||||||
|
|
||||||
Errors reported by the device are raised as :class:`KasaException`\s,
|
Errors reported by the device are raised as :class:`KasaException`\s,
|
||||||
and should be handled by the user of the library.
|
and should be handled by the user of the library.
|
||||||
@@ -75,7 +75,7 @@ class IotStrip(IotDevice):
|
|||||||
All methods act on the whole strip:
|
All methods act on the whole strip:
|
||||||
|
|
||||||
>>> for plug in strip.children:
|
>>> for plug in strip.children:
|
||||||
>>> print(f"{plug.alias}: {plug.is_on}")
|
... print(f"{plug.alias}: {plug.is_on}")
|
||||||
Plug 1: True
|
Plug 1: True
|
||||||
Plug 2: False
|
Plug 2: False
|
||||||
Plug 3: False
|
Plug 3: False
|
||||||
@@ -89,7 +89,7 @@ class IotStrip(IotDevice):
|
|||||||
>>> len(strip.children)
|
>>> len(strip.children)
|
||||||
3
|
3
|
||||||
>>> for plug in strip.children:
|
>>> for plug in strip.children:
|
||||||
>>> print(f"{plug.alias}: {plug.is_on}")
|
... print(f"{plug.alias}: {plug.is_on}")
|
||||||
Plug 1: False
|
Plug 1: False
|
||||||
Plug 2: False
|
Plug 2: False
|
||||||
Plug 3: False
|
Plug 3: False
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ Light, AutoOff, Firmware etc.
|
|||||||
>>> from kasa import Discover, Module
|
>>> from kasa import Discover, Module
|
||||||
>>>
|
>>>
|
||||||
>>> dev = await Discover.discover_single(
|
>>> dev = await Discover.discover_single(
|
||||||
>>> "127.0.0.3",
|
... "127.0.0.3",
|
||||||
>>> username="user@example.com",
|
... username="user@example.com",
|
||||||
>>> password="great_password"
|
... password="great_password"
|
||||||
>>> )
|
... )
|
||||||
>>> await dev.update()
|
>>> await dev.update()
|
||||||
>>> print(dev.alias)
|
>>> print(dev.alias)
|
||||||
Living Room Bulb
|
Living Room Bulb
|
||||||
@@ -18,7 +18,7 @@ To see whether a device supports a group of functionality
|
|||||||
check for the existence of the module:
|
check for the existence of the module:
|
||||||
|
|
||||||
>>> if light := dev.modules.get("Light"):
|
>>> if light := dev.modules.get("Light"):
|
||||||
>>> print(light.brightness)
|
... print(light.brightness)
|
||||||
100
|
100
|
||||||
|
|
||||||
.. include:: ../featureattributes.md
|
.. include:: ../featureattributes.md
|
||||||
@@ -28,7 +28,7 @@ To see whether a device supports specific functionality, you can check whether t
|
|||||||
module has that feature:
|
module has that feature:
|
||||||
|
|
||||||
>>> if light.has_feature("hsv"):
|
>>> if light.has_feature("hsv"):
|
||||||
>>> print(light.hsv)
|
... print(light.hsv)
|
||||||
HSV(hue=0, saturation=100, value=100)
|
HSV(hue=0, saturation=100, value=100)
|
||||||
|
|
||||||
If you know or expect the module to exist you can access by index:
|
If you know or expect the module to exist you can access by index:
|
||||||
@@ -44,8 +44,8 @@ Modules support typing via the Module names in Module:
|
|||||||
>>> light_effect = dev.modules.get("LightEffect")
|
>>> light_effect = dev.modules.get("LightEffect")
|
||||||
>>> light_effect_typed = dev.modules.get(Module.LightEffect)
|
>>> light_effect_typed = dev.modules.get(Module.LightEffect)
|
||||||
>>> if TYPE_CHECKING:
|
>>> if TYPE_CHECKING:
|
||||||
>>> reveal_type(light_effect) # Static checker will reveal: str
|
... reveal_type(light_effect) # Static checker will reveal: str
|
||||||
>>> reveal_type(light_effect_typed) # Static checker will reveal: LightEffect
|
... reveal_type(light_effect_typed) # Static checker will reveal: LightEffect
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
>>> from kasa import Discover
|
>>> from kasa import Discover
|
||||||
>>>
|
>>>
|
||||||
>>> dev = await Discover.discover_single(
|
>>> dev = await Discover.discover_single(
|
||||||
>>> "127.0.0.1",
|
... "127.0.0.1",
|
||||||
>>> username="user@example.com",
|
... username="user@example.com",
|
||||||
>>> password="great_password"
|
... password="great_password"
|
||||||
>>> )
|
... )
|
||||||
>>> await dev.update()
|
>>> await dev.update()
|
||||||
>>> print(dev.alias)
|
>>> print(dev.alias)
|
||||||
Bedroom Power Strip
|
Bedroom Power Strip
|
||||||
@@ -14,7 +14,7 @@ Bedroom Power Strip
|
|||||||
All methods act on the whole strip:
|
All methods act on the whole strip:
|
||||||
|
|
||||||
>>> for plug in dev.children:
|
>>> for plug in dev.children:
|
||||||
>>> print(f"{plug.alias}: {plug.is_on}")
|
... print(f"{plug.alias}: {plug.is_on}")
|
||||||
Plug 1: True
|
Plug 1: True
|
||||||
Plug 2: False
|
Plug 2: False
|
||||||
Plug 3: False
|
Plug 3: False
|
||||||
@@ -28,7 +28,7 @@ Accessing individual plugs can be done using the `children` property:
|
|||||||
>>> len(dev.children)
|
>>> len(dev.children)
|
||||||
3
|
3
|
||||||
>>> for plug in dev.children:
|
>>> for plug in dev.children:
|
||||||
>>> print(f"{plug.alias}: {plug.is_on}")
|
... print(f"{plug.alias}: {plug.is_on}")
|
||||||
Plug 1: False
|
Plug 1: False
|
||||||
Plug 2: False
|
Plug 2: False
|
||||||
Plug 3: False
|
Plug 3: False
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ from .conftest import (
|
|||||||
def test_bulb_examples(mocker):
|
def test_bulb_examples(mocker):
|
||||||
"""Use KL130 (bulb with all features) to test the doctests."""
|
"""Use KL130 (bulb with all features) to test the doctests."""
|
||||||
p = asyncio.run(get_device_for_fixture_protocol("KL130(US)_1.0_1.8.11.json", "IOT"))
|
p = asyncio.run(get_device_for_fixture_protocol("KL130(US)_1.0_1.8.11.json", "IOT"))
|
||||||
|
asyncio.run(p.set_alias("Bedroom Bulb"))
|
||||||
|
asyncio.run(p.update())
|
||||||
|
|
||||||
mocker.patch("kasa.iot.iotbulb.IotBulb", return_value=p)
|
mocker.patch("kasa.iot.iotbulb.IotBulb", return_value=p)
|
||||||
mocker.patch("kasa.iot.iotbulb.IotBulb.update")
|
mocker.patch("kasa.iot.iotbulb.IotBulb.update")
|
||||||
res = xdoctest.doctest_module("kasa.iot.iotbulb", "all")
|
res = xdoctest.doctest_module("kasa.iot.iotbulb", "all")
|
||||||
|
|||||||
Reference in New Issue
Block a user