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:
ZeliardM
2026-07-05 12:30:01 -04:00
committed by GitHub
parent 7f10a39655
commit bb27a43027
18 changed files with 136 additions and 120 deletions

View File

@@ -102,12 +102,12 @@ _LOGGER = logging.getLogger(__name__)
class IotBulb(IotDevice):
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.
All changes to the device are done using awaitable methods,
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
:class:`KasaException <kasa.exceptions.KasaException>`,
@@ -118,7 +118,7 @@ class IotBulb(IotDevice):
>>> bulb = IotBulb("127.0.0.1")
>>> asyncio.run(bulb.update())
>>> print(bulb.alias)
Bulb2
Bedroom Bulb
Bulbs, like any other supported devices, can be turned on and off:
@@ -128,72 +128,82 @@ class IotBulb(IotDevice):
>>> print(bulb.is_on)
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
>>> bulb.is_color
>>> light.has_feature("hsv")
True
>>> bulb.is_variable_color_temp
>>> light.has_feature("color_temp")
True
All known bulbs support changing the brightness:
>>> bulb.brightness
>>> light.brightness
30
>>> asyncio.run(bulb.set_brightness(50))
>>> asyncio.run(light.set_brightness(50))
>>> asyncio.run(bulb.update())
>>> bulb.brightness
>>> light.brightness
50
Bulbs supporting color temperature can be queried for the supported range:
>>> bulb.valid_temperature_range
ColorTempRange(min=2500, max=9000)
>>> asyncio.run(bulb.set_color_temp(3000))
>>> if color_temp_feature := light.get_feature("color_temp"):
... print(
... 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())
>>> bulb.color_temp
>>> light.color_temp
3000
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())
>>> bulb.hsv
>>> light.hsv
HSV(hue=180, saturation=100, value=80)
If you don't want to use the default transitions,
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`
* :func:`turn_off`
* :func:`set_hsv`
* :func:`set_color_temp`
* :func:`set_brightness`
* :meth:`turn_on`
* :meth:`turn_off`
* :meth:`set_hsv`
* :meth:`set_color_temp`
* :meth:`set_brightness`
Light strips (e.g., KL420L5) do not support this feature,
but silently ignore the parameter.
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 }
[{'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 = bulb.modules[Module.LightPreset]
>>> 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`
instance to :func:`save_preset` method:
To modify an existing preset, update one of the entries in
``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
50
>>> preset.brightness = 100
>>> asyncio.run(bulb.save_preset(preset))
>>> asyncio.run(light_preset.save_preset("Light preset 1", preset))
>>> asyncio.run(bulb.update())
>>> bulb.presets[0].brightness
100
>>> light_preset.preset_states_list[0]
IotLightPreset(light_on=None, brightness=100, hue=0, saturation=0, color_temp=2700, transition=None)
""" # noqa: E501

View File

@@ -92,7 +92,7 @@ class IotDevice(Device):
* :class:`IotDimmer`
* :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.
All changes to the device are done using awaitable methods,

View File

@@ -41,14 +41,14 @@ class IotDimmer(IotPlug):
r"""Representation of a TP-Link Smart Dimmer.
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.
All changes to the device are done using awaitable methods,
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,
and should be handled by the user of the library.
@@ -65,7 +65,7 @@ class IotDimmer(IotPlug):
>>> dimmer.brightness
50
Refer to :class:`SmartPlug` for the full API.
Refer to :class:`IotPlug` for the full API.
"""
DIMMER_SERVICE = "smartlife.iot.dimmer"

View File

@@ -16,7 +16,7 @@ class IotLightStrip(IotBulb):
Light strips work similarly to bulbs, but use a different service for controlling,
and expose some extra information (such as length and active effect).
This class extends :class:`SmartBulb` interface.
This class extends :class:`IotBulb` interface.
Examples:
>>> import asyncio
@@ -41,7 +41,7 @@ class IotLightStrip(IotBulb):
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"

View File

@@ -18,12 +18,12 @@ _LOGGER = logging.getLogger(__name__)
class IotPlug(IotDevice):
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.
All changes to the device are done using awaitable methods,
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,
and should be handled by the user of the library.

View File

@@ -53,14 +53,14 @@ class IotStrip(IotDevice):
A strip consists of the parent device and its children.
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.
All changes to the device are done using awaitable methods,
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,
and should be handled by the user of the library.
@@ -75,7 +75,7 @@ class IotStrip(IotDevice):
All methods act on the whole strip:
>>> for plug in strip.children:
>>> print(f"{plug.alias}: {plug.is_on}")
... print(f"{plug.alias}: {plug.is_on}")
Plug 1: True
Plug 2: False
Plug 3: False
@@ -89,7 +89,7 @@ class IotStrip(IotDevice):
>>> len(strip.children)
3
>>> for plug in strip.children:
>>> print(f"{plug.alias}: {plug.is_on}")
... print(f"{plug.alias}: {plug.is_on}")
Plug 1: False
Plug 2: False
Plug 3: False